未声明的标识符编译错误

时间:2012-01-25 09:52:56

标签: c++ include identifier

我正在学习C ++的冷风暴中。我已经了解Java,但C ++在某些方面似乎很奇怪。

这是事情:我有一个A类和一个B类.A类本身有一个B类实例。 B类需要能够调用一些A类方法,所以我在B类的构造函数中放了一个指向A类的指针,并将它存储在一个变量中,这样我就可以用这个变量检索这些方法。

这是我的代码(简化):

ClassA.h

#ifndef CLASSA
#define CLASSA

#include "ParentClass.h"
#include "ClassB.h"

class ClassA : public ParentClass {

private:
ClassB *classB;

public:
ClassA(void);
virtual ~ClassA(void);

};
#endif

ClassA.cpp

   #include "ClassA.h"

   //-----------------------------------------------------
   ClassA::ClassA(void){
    classB= new ClassB(this);
   }
   //-----------------------------------------------------
   ClassA::~ClassA(void)
   {
   }
   //-----------------------------------------------------

ClassB.h

#ifndef CLASSB
#define CLASSB

#include "ClassA.h"

class ClassB{

public:
ClassB(ClassA &pClassA){ classA = pClassA; };
ClassA *getClassAInstance(){ return classA; };

private:
ClassA *classA;
};
#endif

ClassB.cpp

#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?

  

未声明的标识符

为什么呢?我包括了一切,对吗?任何想法有什么不对,伙计们?

4 个答案:

答案 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

ClassB.h

#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)

您在头文件中创建了循环依赖项,它们按顺序包含在内:

  1. ClassA.h
  2. ClassB.h
  3. ClassB中使用时未声明

    ClassA,因为标题ClassB.h将不会再次包含(CLASS_B之前已定义)。

    添加

    class ClassB;
    

    ClassA定义之前。

答案 3 :(得分:0)

要避免这种情况,请尽可能在标头文件中使用forward declaration。这也可以减少编译时间。