4

我有一個繼承自MSFT類的類,因此無法更改,我希望我的派生類具有相同的行爲,用於其複製構造函數和複製賦值運算符。我遇到的麻煩是在複製構造函數中,您可以自由地爲初始化程序列表中的基類調用構造函數,但在運算符中,這不是一個選項。我如何在賦值運算符中正確地重新創建此行爲? 只需在運算符重載的主體中調用基類的構造函數就足夠了嗎? 在複製賦值運算符中分配基類成員

附加說明:基類繼承自CObject,它具有operator =()和拷貝構造函數作爲私有和未實現的方法,所以不幸的是任何調用都會導致編譯錯誤。

我提供以下的簡化的代碼情形:

類聲明:

class Base  
{ 
protected: 
    int baseInt; 
public: 
    Base(int); 
} 

class Derived : public Base 
{ 
public: 
    Derived(const Derived& other); 
    Derived& operator=(const Derived& rhs); 
private: 
    int derivedInt; 
} 

派生類的成員函數:

// Copy Constructor 
Derived(const Derived& other) : Base(5) 
{ 
    derivedInt = other.derivedInt; 
} 

// Copy Assignment Operator 
Derived& operator=(const Derived& rhs) 
{ 
    if (&rhs != this) 
    { 
     derivedInt = other.derivedInt; 
     return *this; 
    } 
} 

編輯:更新語法和加入CObject的音符

+2

'Base(5);'只是創建一個臨時的'Base'對象,然後立即銷燬它... – 2013-04-04 14:43:51

+0

@OliCharlesworth這就是我懷疑會發生的事情:/我不太熟悉如何重新創建一個初始化列表,所以它是在黑暗中拍攝的 – 2013-04-04 14:46:02

回答

5

在一般情況下,你這樣做,或者明確的調用operator =基類子對象,或者通過使用複製&交換成語,如果有的話:

//explicit call to base operator= 
Derived& operator=(const Derived& rhs) 
{ 
    Base::operator=(rhs); // 
    derivedInt = rhs.derivedInt; 
    return *this; 
} 


//or copy&swap: 
Derived& operator=(const Derived& rhs) 
{ 
    Derived tmp(rhs); //copy 
    tmp.swap(*this); 
    return *this; 
} 

void swap(Derived& other) 
{ 
    Base::swap(other); 
    std::swap(derivedInt,other.derivedInt); 
} 

更新:既然你的基類不是爲了拷貝分配的,你的派生類也不應該被拷貝分配。在某些情況下,類包含不可複製的部分,但是完全可以複製。在這些情況下,不可複製的部分是不直接有助於類對象的狀態的,例如,一個唯一的ID。那麼這些部分通常在分配過程中不會被改變。但是,在這些情況下,不可複製的部分不應該被繼承而是通過聚合來包含。

簡言之:繼承意味着「是-A」關係。你的基地不能被複制。你的派生是一個基礎。因此你的Derived也不能被複制。

+0

雖然這似乎可以在大多數情況下工作,但我最終從CObject繼承,它的賦值運算符/拷貝構造函數是私有的。另外,'swap()'沒有在基類中實現,也沒有在它的任何基礎上實現,所以這也不起作用:/我已經更新了我的問題來反映這個 – 2013-04-04 15:06:32

+1

然後你不應該提供複製機制(參見我的編輯) – 2013-04-04 15:13:38

+0

好的,謝謝。我的靜態分析工具抱怨缺少'operator =',所以我認爲它必須在那裏,儘管在基地是私人的。謝謝(你的)信息! – 2013-04-04 15:16:32

2

這樣的

Derived& operator=(const Derived& rhs) 
{ 
    Base::operator=(rhs); 
    derivedInt = rhs.derivedInt; 
    return *this; 
}