2015-10-04 109 views
0

無法編譯以下內容。這裏有什麼不對?錯誤:沒有適當的默認構造函數

class B; 
class A 
{ 
public: 
    void DoSomething() 
    { 
     ... 
     B* myb = new B(); 
     ... 
    } 
}; 

class B 
{ 
public: 
B() {} 
}; 
+1

什麼是錯誤,並把整個代碼請。 – Bill

+0

在創建它的一個實例之前,'B'的完整定義需要可見。單靠前向宣言是不夠的。 –

+0

C2512是錯誤代碼。 「'B':沒有適當的默認構造函數可用」@Igor Tandetnik - 我想你是對的。但如何解決這個問題? – Anand

回答

1

new B()要求完整的類型定義。前向聲明是不夠的。

這是有道理的。例如,誰說B甚至有一個公共的默認構造函數?在B的完整定義已知之前,您無法知道。

1

爲了知道某些class B存在,您做了前向聲明,儘管它尚未定義。在這種情況下,您甚至不需要這樣做,因爲B類型的class A中沒有成員。

剛剛宣佈doSomething方法,後來把它定義B定義

class A { 
    ... 
    void doSomething(); // declared 
    ... 
}; 

class B { 
    ... 
}; 

// define doSomething after defining class B or in the .cpp source file 
void A::doSomething() { 
    B *myb = new B(); 
    ... 
} 

後,雖然通常你會用頭/源文件,所以它會比較實用的聲明自定義分開。


編輯

如果A和B都稱呼對方,那麼你需要寫在其中的一個(或兩個)正向聲明。

// A.h 
class B; 
class A { 
    ... 
    B *_myB; 
}; 

// A.cpp 
#include "B.h" 

void A::doSomething() { 
    _myB = new B(); 
} 

// B.h 
class A; 
class B { 
    ... 
    A *_myA; 
}; 

// B.cpp 
#include "A.h" 

void B::doSomething() { 
    _myA = new A(); 
} 

預先聲明可以讓你有一個指針類型,如B*。但不是完整的類型B,因爲B的大小未知,但B*與任何其他指針的大小相同。

您可以通過在頭文件中包含其他類來存儲完整類型,但不能同時包含這兩種類型。

無論如何,如果您可以包含依賴完整類型,這是沒有意義的。然後,A的一個實例將實例化成員B,該成員又將實例化其成員A等等。

+0

真棒。那就是我必須做的。非常感謝您向非常簡單的技術展示燈光,並且必須記住技術。 – Anand

0

當你轉發聲明一個類型時,你告訴編譯器這樣一個類型exists.But編譯器不知道該類型的大小或成員。

您通常使用前向聲明來打破循環依賴關係。

class B; 
class A 
{ 
public: 
    void DoSomething() 
    { 
     ... 
     B* myb ;   ... 
    } 
}; 

這將工作,因爲你只有一個指向該類型的指針。

這已經在這裏詳細討論: forward reference usage

0
class B; 

上面的聲明(向前聲明)推出名稱到編譯器。聲明之後並且在定義出現之前,鍵入B不完整類型

使用不完整類型是有限的。例如,指針或引用可以定義爲這種類型。但是,這是不可能的;

  • 創建(編譯器不知道之類的大小)
  • 訪問類型的成員(編譯器不知道班裏有什麼成員),該類型的對象

在有問題的代碼中;

B* myb = new B(); 

是在聲明之後並且在定義出現之前。

相關問題