我正在学习C ++的冷风暴中。我已经了解Java,但C ++在某些方面似乎很奇怪。
这是事情:我有一个A类和一个B类.A类本身有一个B类实例。 B类需要能够调用一些A类方法,所以我在B类的构造函数中放了一个指向A类的指针,并将它存储在一个变量中,这样我就可以用这个变量检索这些方法。
这是我的代码(简化):
#ifndef CLASSA
#define CLASSA
#include "ParentClass.h"
#include "ClassB.h"
class ClassA : public ParentClass {
private:
ClassB *classB;
public:
ClassA(void);
virtual ~ClassA(void);
};
#endif
#include "ClassA.h"
//-----------------------------------------------------
ClassA::ClassA(void){
classB= new ClassB(this);
}
//-----------------------------------------------------
ClassA::~ClassA(void)
{
}
//-----------------------------------------------------
#ifndef CLASSB
#define CLASSB
#include "ClassA.h"
class ClassB{
public:
ClassB(ClassA &pClassA){ classA = pClassA; };
ClassA *getClassAInstance(){ return classA; };
private:
ClassA *classA;
};
#endif
#include "ClassA.h"
/*ClassB::ClassB(void){
classA= pClassA;
}*/
Visual Express不会出错,但是当我编译时,它说B类不能识别什么是A类。
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(8):错误C2061:语法 错误:标识符'ClassA'
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(10):错误C2143:语法 错误:缺少';'在'*'之前
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(10):错误C4430: 缺少类型说明符 - 假设为int。注意:C ++不支持 默认int
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(10):错误C4430: 缺少类型说明符 - 假设为int。注意:C ++不支持 默认int
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(10):警告C4183: 'getClassAInstance':缺少返回类型;假设是会员 函数返回'int'
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(13):错误C2143:语法 错误:缺少';'在'*'之前
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(13):错误C4430: 缺少类型说明符 - 假设为int。注意:C ++不支持 默认int
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(13):错误C4430: 缺少类型说明符 - 假设为int。注意:C ++不支持 默认int
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(8):错误C2065: 'classA':未声明的标识符
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(8):错误C2065: 'pClassA':未声明的标识符
1> c:\ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ xxx \ ClassB.h(10):错误C2065: 'classA':未声明的标识符
未申报什么?返回int?
未声明的标识符
为什么呢?我包括了一切,对吗?任何想法有什么不对,伙计们?
答案 0 :(得分:5)
这是因为头文件之间存在循环引用。你可以通过向前声明另一个标题中的一个类来打破它,如下所示:
#ifndef CLASSA
#define CLASSA
#include "ParentClass.h"
//#include "ClassB.h" <<<<< Circular reference is now broken
class ClassB; // Added a forward declaration for use below.
class ClassA : public ParentClass {
private:
ClassB *classB;
public:
ClassA(void);
virtual ~ClassA(void);
};
#endif
答案 1 :(得分:1)
class A
中的class B
标头和class B
中的class A
标头正在形成循环依赖关系。这就是你得到编译器错误的原因。而是尝试在其中一个头文件中使用Forward Declaration
。
#ifndef CLASSB
#define CLASSB
class ClassA; //forward declaration of ClassA
class ClassB{
public:
ClassB(ClassA* pClassA){ classA = pClassA; };
ClassA *getClassAInstance(){ return classA; };
private:
ClassA *classA;
};
#endif
并在ClassA
中加入ClassB.cpp
的标头文件,以访问ClassA
成员的实施。
答案 2 :(得分:1)
您在头文件中创建了循环依赖项,它们按顺序包含在内:
ClassB
中使用时未声明 ClassA
,因为标题ClassB.h将不会再次包含(CLASS_B
之前已定义)。
添加
class ClassB;
在ClassA
定义之前。
答案 3 :(得分:0)
要避免这种情况,请尽可能在标头文件中使用forward declaration。这也可以减少编译时间。