我遇到了一个循环依赖问题,其中包含头的顺序很重要。 这个问题类似,但是它没有记录一个类实例化另一个类的对象的解决方案。
问题:
在下面的代码中,如果main.cpp在foo.h之前包含bar.h,则代码会编译,如果foo.h在bar.h之前包含,则代码不会编译。 有没有一种方法可以使代码编译,而不考虑main.cpp中包含头的顺序?
FOO.H
#ifndef FOO_H
#define FOO_H
#include"Bar.h"
class Foo
{
public:
Bar<> B;
void fooStuff(){};
};
#endif
Bar.H
#ifndef BAR_H
#define BAR_H
class Foo;
template<int N=0> class Bar
{
public:
Foo * F;
void barStuff();
};
#include"Foo.h"
template<int N> void Bar<N>::barStuff()
{
F->fooStuff();
};
#endif
main.cpp
#include"Foo.h"
#include"Bar.h"
int main()
{
Foo F;
F.B.barStuff();
};
是:在bar
之前声明foo
,因为bar
只使用指针,不需要完整定义。 然后在bar
之后定义foo
-它使用了一个对象,因此它确实需要定义。
class Foo;
template<int N> class Bar
{
public:
Foo * M;
void barStuff();
};
class Foo
{
public:
Bar<42> B;
void fooStuff(){}
};
template<int N> void Bar<N>::barStuff()
{
M->fooStuff();
}
通常,对于需要类的任何属性(如其大小或成员)的任何内容,您都需要完整的定义,并且只需要在声明函数,指针或引用时使用类名的声明。
我需要在Foo之前包含Bar,无论它们在main.cpp中的包含顺序如何。 下面的黑客似乎很有效:
在foo.h中,将bar.h包括在标题保护之外。 由于Bar也有头球护卫,所以它不会多次被包括在内。
FOO.H
#include"Bar.h"
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
Bar<> B;
void fooStuff(){};
};
#endif
Bar.H
#ifndef BAR_H
#define BAR_H
class Foo;
template<int N=0> class Bar
{
public:
Foo * F;
void barStuff();
};
#include"Foo.h"
template<int N> void Bar<N>::barStuff()
{
F->fooStuff();
};
#endif
main.cpp
#include"Foo.h"
#include"Bar.h"
int main()
{
Foo F;
F.B.barStuff();
};