| 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