Jon Stewart on 6 Jun 2002 22:47:22 -0000


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [hosers-talk] classes with pointers to each other


> How do I make this work?


This I can answer...


> class Foo {
>    public:
>       List<Bar> *list;
> }
> 
> class Bar {
>    public:
>       List<Foo> *list;
> }


When headers reference each other, do this:

// Foo.h

class Bar;

class Foo {
public:
	List<Bar*> *list;
};


// Bar.h

class Foo;

class Bar {
public:
	List<Foo*> *list;
};


By only referencing pointers to the second class, C++ can deal because it 
doesn't have to know anything about the second's members or the value of 
sizeof(second class). So, this will compile, no problem.

Two other benefits:

1. Decreased compile-time. Including headers within a header is the #1 way 
to increase your compile-time. So, using empty class declarations like 
this will keep your compile-times low.

2. You're much less likely to make copies if you're storing pointers. So, 
it can be a performance win.

One downside:

1. Your compile will generate different template implementations for each 
kind of pointer you parametize it with. So, you can get binary bloat. 
There are techniques to mitigate this; let me know if you want to use 
them.


> The lists are for keeping track of which Foo are associated with which Bar 
> and vice versa, since it would be much slower if, each time I need to know 
> which Foo are associated with a particular Bar, I have to check every Foo. 


There are a couple ways to do this. First of all, each Foo is keeping 
track of every Bar (and vice versa). If it's one-to-one, then have each 
Foo have a single pointer to a Bar. If the association doesn't change 
during the object's lifetime, then you can be a badass and make Foo have a 
reference to a Bar, which is passed in at construction. I tend to think 
this is the better solution.

Or, as you seem to want to, if you want to keep Foos and Bars more-or-less
separate but be able to look up associations between them in a big data
structure, have a double map:

std::map< Foo*, Bar* > foo2bar;
std::map< Bar*, Foo* > bar2foo;

Std::maps rule. If you want, I can whip up a template for a double map, 
based on std::map.


> Can classes be interdefined like this?


Yes. See if you can't check out _Design Patterns_ by Gamma, Helm, Johnson, 
Vlissides at the library. Makes object relationships easier to understand.

And for God's sake, if you aren't already, use the STL.



Jon
-- 
Jon Stewart
stew1@xxxxxxxxxxx

"and dropping a barbell, he points to the sky, saying 'the sun's not 
yellow, it's chicken.'"

			-- Bob Dylan