假设我有2个分类:
// a.h
#ifndef A_H
#define A_H
#include "b.h"
class A {
public: void a() {
B* b = new B(this);
}
}
#endif
// b.h
#ifndef B_H
#define B_H
#include "a.h"
class B {
public: B(A* a) {
// ...
}
}
#endif
此代码将引发错误A has not been declared
,因为类A引用了类B,而类B又引用了尚未在a.h中声明的类A.
那么如何将A的实例传递给B?
答案 0 :(得分:4)
你需要
B
构造函数的pass-by-value参数更改为指针或引用* B::B
的定义移至cpp文件(这将删除对A
定义的任何直接依赖,并允许您 转发声明 A
:
// b.h
#ifndef B_H
#define B_H
class A;
class B {
public: B(const A& a) {
// ...
}
}
#endif
// b.cpp
#include "b.h"
#include "a.h"
public B::B(const A& a) {
// ...
}
请注意,我为const
构造函数参数添加了A&
限定符,因为我假设您不想在a
的构造函数中修改B
。 / p>
当然,您也可以通过将A::a
的定义和相应的#include "b.h"
移动到a.cpp中来反过来播放。
* 无论如何你最有可能这样做,因为你不太可能想要按值传递A
对象。按值传递对象意味着隐式创建对象的副本并将其推送到堆栈。哪个
答案 1 :(得分:1)
您将实现移到单独的文件中。这样您就不必在B.h
中包含A.h
:
// a.h
class A {
public:
void a();
};
// b.h
#include "a.h"
class B {
public:
B(A a) { }
};
// a.cpp
#include "a.h"
#include "b.h"
void A::a(){
B* b = new B(*this); //B constructor doesn't take a pointer
}
答案 2 :(得分:0)
使用语法
向前声明一个类class A;
在你的b.h文件中,这足以告诉编译器有一个名为A的类,你将引用它。它不允许你访问该类的内部(例如,你没有告诉它它有什么成员,或它有多大),但它足以用作指针或引用。
您可以做的另一件事是查看您的设计并尝试删除此类循环依赖项。