2010-01-17 76 views
4

假設我有一個基類Person,並且我公開繼承了基類Person中的類Teacher。 現在在主函數中我寫的是這樣的面向對象編程,繼承,複製構造函數

// name will be passed to the base class constructor and 17 
// is for derived class constructor. 
Teacher object(「name」,17) ; 
Teacher object1=object; //call to copy constructor 

現在我沒有寫拷貝構造函數爲兩個類,關閉過程中,默認的拷貝構造函數將被調用。 Person類的默認拷貝構造函數將首先調用基類的拷貝構造函數。現在

問題是假設我寫的基類唯一的,是發生了什麼,派生類的默認拷貝構造函數會叫我寫的拷貝構造函數拷貝構造函數。
現在假設我爲這兩個類編寫了複製構造函數。現在派生類(即Teacher)的複製構造函數將調用基類的默認構造函數,但不會調用複製構造函數爲什麼?
是派生類中唯一的缺省拷貝構造函數可以自動調用基類的拷貝構造函數?

+0

沒有「Default Copy Constructor」這樣的東西。但是編譯器生成的拷貝構造函數會調用基類的拷貝構造函數。 – 2010-01-17 20:44:51

+0

現在,謝謝你,我明白了這一點。 – 2010-01-17 20:49:36

回答

8

你必須明確地調用基複製構造函數:

Teacher(const Teacher& other) 
    : Person(other) // <--- call Person's copy constructor. 
    , num_(other.num_) 
{ 
} 

否則Person的默認構造函數將被調用。


我似乎沒有完全理解這個問題,所以我只是說一切我認爲是相關的,希望這將有助於OP。

所有的用戶定義的構造函數默認調用他們的基地的默認構造函數(除非他們明確地調用不同的構造函數),如果基本的默認構造函數是用戶定義或編譯器生成的也沒關係。

當編譯器生成拷貝構造函數時,它將調用基類的拷貝構造函數。

編譯器定義的構造並不特別,他們可以明確地稱爲:

class Base { 
    int num_ 
public: 
    Base(int n) : num_(n) { } 
    // copy constructor defined by compiler 
}; 

class Derived : public Base { 
    float flt_; 
public: 
    Derived(float f, int n) : Base(n), flt_(f) { } 
    // Copy constructor 
    Derived(const Derived& other) 
     : Base(other) // OK to explicitly call compiler generated copy constructor 
     , flt_(other.flt_) 
    { 
    } 
}; 

欲瞭解更多詳細信息,請參閱本Wikipedia article

+0

你知道,我必須明確地調用它,但這不是我的問題,我的問題是「派生類的唯一默認拷貝構造函數可以調用基類的複製構造函數(默認或用戶書寫)」? – 2010-01-17 20:27:54

+1

我不明白你的問題。 – Motti 2010-01-17 20:29:15

+0

只是派生類的默認拷貝構造函數可以自動調用基類的拷貝構造函數,基類的拷貝構造函數是默認拷貝構造函數還是用戶寫入拷貝構造函數?是否有意義? – 2010-01-17 20:33:04

1

如果您未指定複製構造函數,編譯器會自動生成一個。這個構造函數的生成方式是它調用基類的複製構造函數。

如果實現拷貝構造函數自己,你還可以指定哪些基類的構造函數應使用(見Motti的回答)。如果不指定任何內容,則使用默認構造函數(這就是爲什麼它被稱爲「默認構造函數」的原因:在沒有明確指定構造函數時使用它)。

所以編譯器會自動生成一個合理的拷貝構造函數,但如果你想一些特別的東西沒有進一步的魔術是怎麼回事,你必須指定你自己怎麼說的構造究竟應該像。

1
class Base { 
    int num_ 
public: 
    Base(int n) : num_(n) { } 
    // copy constructor defined by compiler 
}; 

class Derived : public Base { 
    float flt_; 
public: 
    Derived(float f, int n) : Base(n), flt_(f) { } 
    // Copy constructor 
    Derived(const Derived& other) 
     : Base(other) // OK to explicitly call compiler generated copy constructor 
     , flt_(other.flt_) 
    { 
    } 
};