2016-06-07 128 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