This question already has an answer here:
FILE #1 (foo.h):
#ifndef FOO_H_
#define FOO_H_
#include "baseclass.h"
#include "bar.h"
class Bar;
class Foo : public baseclass {
public:
bar *varBar;
};
#endif
FILE #2 (bar.h):
#ifndef BAR_H_
#define BAR_H_
#include "foo.h"
class Foo;
class Bar {
public:
Foo *varFoo;
};
#endif
FILE #3 (baseclass.h):
#ifndef BASECLASS_H_
#define BASECLASS_H_
#include "foo.h"
class Foo;
class baseclass {
public:
list<Foo*> L;
};
#endif
But I get an compile error in file #1 in line class Foo : public baseclass
:
Error: expected class-name before »{« token
If I add class baseclass;
bevor class declaration, I get this error:
Error: invalid use of incomplete type »struct baseclass«
So my question is, how can I resolve circular dependencies with baseclasses?
Ask if you don't get somepoint. I allready tried to change the order of includeing the headers, but no luck so far. Thanks for any hint.
EDIT: Note: I am using include guards EDIT2: It is not limited to pointers, so I remove them, just in case. EDIT3: Added baseclass (forgot O.o) EDIT4: Now it should be clear and without anymore flaws, the problem persisits with this code.
What you seem to have posted is to have a
Bar
member in theFoo
, and aFoo
member in theBar
. That is a circular dependency you need to break - if everyFoo
contains aBar
which contains aFoo
then constructing either never terminates.Instead you need to use a pointer or reference to the
Foo
orBar
in at least one of them:As the circularity is broken and you're only using a reference to the object, you don't need to have the full definition of the referred-to type, and can use a forward declaration.
Include guards are good for users, but try and not rely on them when developing. If the compiler has to check whether or not something has been included, it's still doing work even if it has optimisations for guards/pragmas. You do need to have some understanding of what depends on what to break the initial cycle, and putting guards on the files won't help you with that.
The usual way is to add the following around your header files:
and
Most compilers (gcc, VC) also accept
#pragma once
at the beginning of the file, but I'm pretty sure it is not part of the current C++ standard.EDIT:
Sure enough, as the ISO/IEC 14882 states, a #pragma "
causes the implementation to behave in an implementation-defined manner. Any pragma that is not recognized by the implementation is ignored.
"It is currently still the same with C++0x.
So I would stick with the first old-fashioned way of doing that ;-)
If a class is forward declared and you are using only a pointer or a reference to a member of that class, then you do not need to include the header for it. The same goes for the class in the other file. But yes, make sure that you use include guards in all of your header files (
#ifndef...#endif
) to prevent multiple inclusions of headers during compilation.Do you have include guards on your headers? The code above includes a.h and b.h recursively, thus defining a whole bunch of headers.
The forward declaration
class b;
removes the need for the#include "b.h"
in FILE1. Similarly,#include "a.h"
should be removed from FILE2.baseclass.h
doesn't need anything fromfoo.h
, so remove#include "foo.h"
frombaseclass.h
.You have a
Foo
variable in yourBar
, and aBar
in yourFoo
. That isn't going to work: you can't have an egg in a box and a box in an egg. One or both of them should be a pointer.