2016-06-07 133 views
0

下面是代码C++这是一个不完整类型?

#include <iostream> 

#include "ClassA.h" 

ClassA* class_a = new ClassA(); 

int main() { 



    return 0; 
} 

A类

#ifndef CLASSA_H 
#define CLASSA_H 

#include <iostream> 
#include "ClassB.h" 

class ClassA 
{ 
public: 
    ClassA() 
    { 
     ClassB classB = new ClassB(); 

     std::cout << "End of constructor" << std::endl; 
    } 

    void ClassA::DoSomething(void) 
    { 
     std::cout << "ClassA DoSomething"; 
    } 
}; 


#endif /* CLASSA_H */ 

B类

#ifndef CLASSB_H 
#define CLASSB_H 

class ClassA; 

extern ClassA* class_a; 

class ClassB 
{ 

public: 

    ClassB() 
    { 
     ::class_a->DoSomething(); 
     std::cout << "ClassB constructor" << std::endl; 
    } 

}; 


#endif /* CLASSB_H */ 

ClassB的构造我在::class_a->DoSomething();member access into incomplete type "ClassA"得到一个编译错误。但是,在解析ClassB的构造函数时,ClassA不完整?当它通过ClassA时,它会在它的构造函数中获得类型ClassB,然后希望通过该文件?

+0

编译器不会欺骗你。 'ClassA'在解析'class_a-> DoSomething();'行时确实没有定义。尝试将.h文件的内容放在一个.cc文件中,并检查.cc文件的内容。 –

+0

很明显。 “B”中的“A”的定义在哪里?你只有一个前向声明,因此除了存储引用(指针或ref)之外,你不能做任何事情。 – luk32

回答

3

这是一个不完整的类型,因为你还没有列入ClassBClassA头,而是你试图使用ClassA实例。换句话说,编译器知道有一个ClassA感谢forward声明,这足以声明一个指针,但类型是不完整的,不能使用,因为编译器没有看到类型的声明。您需要创建一个源文件(例如ClassB.cpp),在源文件中包含ClassA标头,并将构造函数的构造函数的实现移动到源文件中。

0

让我们看看这个从编译的点已经处理了之后包括:

#line 1 main.cpp 
//#include <iostream> 
/* Text of iostream inserted here */ 
//#include "ClassA.h" 
#line 1 ClassA.h 

//#ifndef CLASSA_H (it isn't defined) 
#define CLASSA_H 

//#include <iostream> 
/* Almost nothing here because iostream has already been included */ 

//#include "ClassB.h" 
#line 1 ClassB.h 
//#ifndef CLASSB_H (again, it isn't defined) 
#define CLASSB_H 

class ClassA; 

extern ClassA* class_a; 

class ClassB 
{ 

public: 

    ClassB() 
    { 
     ::class_a->DoSomething(); 

权。所以我们编译main.cpp,其中包括ClassA.h,其中包括ClassB.h。在我们到达这里的时候,ClassA没有被定义。

将(至少)其中一个构造函数移动到单独的.cpp文件中。

+0

因此编译器在完成一个文件之前不能正常工作,然后再转到下一个文件?它跟随'#include ...'去接受它? – j76goatboy