2012-06-11 89 views
4

從我對C++繼承的理解中可以看出,每當調用子類的構造函數時,父類的構造函數都會自動調用。至於模板化構造函數,模板參數的數據類型會自動傳遞,即我們不需要單獨指定模板參數。該程序生成一個編譯錯誤,我似乎不明白。產生C++繼承類的模板構造函數

test.cpp: In function ‘int main()’: 
test.cpp:56:8: error: no matching function for call to ‘D::D(A&)’ 
test.cpp:56:8: note: candidates are: 
test.cpp:44:7: note: D::D() 
test.cpp:44:7: note: candidate expects 0 arguments, 1 provided 
test.cpp:44:7: note: D::D(const D&) 
test.cpp:44:7: note: no known conversion for argument 1 from ‘A’ to ‘const D&’ 

#include <iostream> 
#include <list> 
#include <algorithm> 

using namespace std; 

class A{ 
    public: 
    int x; 
    int y; 
    int first(){ 
     return x; 
    } 
    int second(){ 
     return y; 
    } 
}; 

class C{ 
    public: 
    float a,b; 
    C(){ 
     a = 0.0f; 
     b = 0.0f; 
    } 
    template<class T> 
     C(T t){ 
     a = t.first(); 
     b = t.second(); 
     } 
}; 

class D: public C{ 
    public: 
    float area(){ 
     return a*b; 
    } 
} 

int main(){ 
    A a; 
    a.x = 6; 
    a.y = 8; 
    C c(a); 
    D d(a); 
    cout<<c.a<<" "<<c.b<<" "<<d.area()<<endl; 
} 

編譯錯誤,我不知道這裏發生了什麼。有任何想法嗎?

+0

http://stackoverflow.com/questions/347358/inheriting-constructors –

回答

5

D必須將構造函數參數傳遞給C,因爲您沒有使用默認構造函數。

class D : public C { 
public: 
    template <typename T> D (T t) : C(t) {} 
    float area() { /* ... */ } 
}; 

的原因錯誤是,你要建D一個參數,但沒有宣佈任何構造函數,將允許你這樣做。此外,您必須將參數傳遞給C,否則編譯器將使用C的默認構造函數。

編譯器錯誤信息可以像這樣分析。

test.cpp:56:8: error: no matching function for call to ‘D::D(A&)’ 

編譯器抱怨:

D d(a); 

而且它無法弄清楚如何在傳遞A類型的東西構造D

然後,它提出了構造的兩種選擇它知道:

test.cpp:44:7: note: D::D() 
test.cpp:44:7: note: D::D(const D&) 

它指出,對於每一個,有它不能使用它的理由。對於第一個,它沒有任何爭論。對於第二個,它沒有辦法將A類型的東西轉換爲D類型。

+1

的潛在重複我同意你的解決方案可能的作品,你的理由看起來不錯,但我會補充說,在他的錯誤最後2行顯示編譯器可能試圖在D的拷貝構造函數中「推斷」,編譯器可以自行生成。這個額外的錯誤也可能令OP難以理解。 –

+0

@Kevin:感謝您的反饋,我擴展了錯誤信息的解釋。問候。 – jxh

1

從我對C++的繼承的理解是,每當調用子類的構造函數時,父類的構造函數都會自動調用。

小心:父類的構造函數會自動使用與子類的構造函數相同的參數進行調用。

至於具體的問題:沒有爲D類聲明構造函數。你將得到一個默認的構造函數和複製構造函數作爲自由空間,但不是類C中的基於模板的構造函數。構造函數不會繼承。