forward declaration with vector of class type - pointer to incomplete class type not allowed
I have two classes, foo
and bar
.
foo.h #include
s bar.h and contains a std::vector
of pointers to bar
objects. At some point during runtime, bar
has to access this vector of pointers to other bar
objects. Therefore, foo
contains a method named getBarObjects()
that returns the array of pointers.
Therefore, I forward declare foo
in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects()
. As this returns the array of pointers to bar
, I get into a vicious cycle.
I cannot forward declare Bar and then simply forward declare getBarObjects()
, as this results in "incomplete type name is not allowed".
foo.h:
#include "bar.h"
#include <vector>
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
}
bar.h:
class foo;
std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp:
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
}
If I simply include the other way around, I'll have just the same problem in foo
later on. Any suggestions?
Solution 1:
You can't forward declare members.
Instead, bar.cpp
should #include
both foo.h
and bar.h
. Problem solved.
In general, if you use the sequence:
- Forward declare all class types
- Define all class types
- Bodies of class members
everything will be fine.
Solution 2:
You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.
foo.h
#include <vector>
class bar;
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
};
bar.h
class foo;
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp
#include "foo.h"
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects();
}