2011-04-08 144 views

回答

5

像正常的類:是的,如果你有一個具體的實施需求。

2

如果它是您計劃複製的對象,那麼這是個好主意。如果不是,請參閱下面的評論。

如果您的虛擬基類依賴於需要顯式分配和複製的資源(緩衝區,操作系統對象等),那麼定義複製構造函數可以避免在每個派生類中分別執行此操作的麻煩(並且,另外,如果這些基礎資源是私有的,則使用公有繼承)。

例如爲:

class Base { 
public: 
    Base(const Base &); 
    virtual ~Base(); 
    virtual void Method() = 0; 
    // etc... 
private: 
    int *memberIntArray; 
    int length; 
    // etc... 
}; 

class DerivedOne : public Base{ 
public: 
    DerivedOne(const DerivedOne &); 
    virtual ~DerivedOne(); 
    virtual void Method(); 
    // etc... 
protected: 
    // data, etc... 
}; 

class DerivedTwo : public Base{ 
public: 
    DerivedTwo(const DerivedTwo &); 
    virtual ~DerivedTwo(); 
    virtual void Method(); 
    // etc... 
protected: 
    // data, etc... 
}; 

/////////////////// 

Base::Base(const Base & other) { 
    this->length = other.length; 
    this->memberIntArray = new int[length]; 
    memcpy(this->memberIntArray,other.memberIntArray,length); 
} 

//etc... 

DerivedOne::DerivedOne(const DerivedOne & other) 
    : Base(other) 
{ 
    //etc... 
} 

DerivedTwo::DerivedTwo(const DerivedTwo & other) 
    : Base(other) 
{ 
    //etc... 
} 
+0

我只是補充說應該使用一個拷貝構造函數來重載=操作符。它提高了可讀性,並且不易出錯。 – janhink 2011-04-08 09:41:58

+5

我真的很喜歡將私有空副本構造函數和賦值運算符聲明爲一切。這樣,如果我試圖不恰當地複製某些內容,編譯器會抱怨。只有當我確實需要*可複製的對象時,我纔會公開這些內容。你可能會開懷大笑,但是當我開始練習時,你會驚訝地發現有多少問題得到解決。 ;) – Nate 2011-04-08 09:55:28

0

是的,你應該。
即使是抽象類也適用於您爲自己的複製構造函數,複製賦值運算符和析構函數實現的規則。
另外,看看Rule of Three

0

這取決於你的使用情況,如果你沒有做任何事情需要複製處理,例如,複製句柄。如果需要,你最好在派生類中定義一個拷貝構造函數。

4

如果它只有純粹的虛擬方法(並且沒有數據成員),那麼,不,合成的很好(並且不會做任何事情)。

如果它確實有數據成員,那麼你應該定義自己的拷貝構造函數,如果/當它有意義的時候,就像其他任何類一樣。派生類與它沒有多大關係。