可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm looking to create two classes, each of which contains an object of the other class type. How can I do this? If I can't do this, is there a work-around, like having each class contain a pointer to the other class type? Thanks!
Here's what I have:
File: bar.h
#ifndef BAR_H #define BAR_H #include "foo.h" class bar { public: foo getFoo(); protected: foo f; }; #endif
File: foo.h
#ifndef FOO_H #define FOO_H #include "bar.h" class foo { public: bar getBar(); protected: bar b; }; #endif
File: main.cpp
#include "foo.h" #include "bar.h" int main (int argc, char **argv) { foo myFoo; bar myBar; }
$ g++ main.cpp
In file included from foo.h:3, from main.cpp:1: bar.h:6: error: ‘foo’ does not name a type bar.h:8: error: ‘foo’ does not name a type
回答1:
You cannot have two classes directly contain objects of the other type, since otherwise you'd need infinite space for the object (since foo has a bar that has a foo that has a bar that etc.)
You can indeed do this by having the two classes store pointers to one another, though. To do this, you'll need to use forward declarations so that the two classes know of each other's existence:
#ifndef BAR_H #define BAR_H class foo; // Say foo exists without defining it. class bar { public: foo* getFoo(); protected: foo* f; }; #endif
and
#ifndef FOO_H #define FOO_H class bar; // Say bar exists without defining it. class foo { public: bar* getBar(); protected: bar* f; }; #endif
Notice that the two headers don't include each other. Instead, they just know of the existence of the other class via the forward declarations. Then, in the .cpp files for these two classes, you can #include
the other header to get the full information about the class. These forward declarations allow you to break the reference cycle of "foo needs bar needs foo needs bar."
回答2:
That doesn't make sense. If A contains B, and B contains A, it would be infinite size. Imagine putting having two boxes and trying to put both into each other. Doesn't work, right?
Pointers work though:
#ifndef FOO_H #define FOO_H // Forward declaration so the compiler knows what bar is class bar; class foo { public: bar *getBar(); protected: bar *b; }; #endif