2013-04-24 86 views
0

下面的C++代碼不能編譯:C++:是否有可能繼承賦值運算符?

class BaseA { 
protected: 
    BaseA &operator = (const BaseA &rhs); 
}; 

template<typename T> 
class BaseB { 
public: 
    T &operator = (const T &rhs) { 
     return *static_cast<T *>(this); 
    }; 
}; 

class Derived : 
    public BaseA, 
    public BaseB<Derived> { 
}; 

int main() { 
    Derived foo; 
    Derived bar; 
    foo = bar; 
    return 0; 
}; 

當我嘗試編譯此我得到一個抱怨BaseA &BaseA::operator = (const BaseA &)是不確定的。在stackoverflow上還有其他幾個類似的問題,但它們似乎都涉及編譯器自動生成Derived &Derived::operator = (const Derived &)函數,它調用BaseA::operator = (const BaseA&)。在這種情況下,儘管Derived應該已經從BaseB<Derived>繼承了具有該確切簽名的功能。如果我按照另一個問題的建議,並將using BaseB<Derived>::operator =;添加到Derived編譯器抱怨Derived &operator = (const Derived &)不能重載。

是它根本不可能爲一個類繼承這個操作?

編輯:要清楚,我很困惑,爲什麼編譯器是給Derived默認Derived &operator = (const Derived &)時,它已經繼承Base<Derived>T &operator (const T &) where [T = Derived]。我可以理解爲什麼默認的拷貝賦值運算符通常會被創建,並覆蓋任何繼承賦值運算符,但在這種情況下Derived被繼承的操作與完全相同的簽名的拷貝賦值運算符。有沒有辦法寫BaseB以便它的子類使用這個操作符?

+0

我不確定這個錯誤與您的問題有何關係。你得到這個錯誤是因爲你聲明瞭這個函數,但從來沒有定義它。 – 2013-04-24 03:56:53

+0

由於您只聲明瞭BaseA&operator =',因此編譯器非常正確。將其更改爲'BaseA&operator =(const BaseA&rhs)= default;'並且它會很愉快地編譯。 – Yuushi 2013-04-24 03:58:19

+0

鏈接器不應該關心它沒有被定義,因爲它永遠不會被調用。它會被調用的唯一原因是編譯器正在生成它自己的Derived :: operator =(const Derived&)函數。 – Shum 2013-04-24 04:01:06

回答

0

可以繼承基類的運營商和所有其他的方法,如果你沒有在基類中聲明它 - 默認賦值運算符將被編譯器生成,如果你聲明它 - 當你必須提供你自己的實現,所以你由於operator =而得到的錯誤未在您的BaseA類中定義,只聲明。

5

沒有,賦值運算符operator=不被繼承。 您的Derived類中沒有默認的

Derived& operator=(const BaseA& a); 

默認的賦值運算符,但是,創建:

Derived& operator=(const Derived& a); 

,這從BaseA調用賦值運算符。所以這不是繼承賦值運算符的問題,而是通過派生類中的默認生成運算符調用它。 還有一些注意事項: 標準說(12.8):

賦值運算符應以非靜態成員函數 正好有一個參數來實現。因爲複製賦值運算符 運算符=被隱含了一類聲明,如果沒有聲明 由用戶(12.8),基類賦值運算符總是由派生類的複製賦值運算符隱藏 。衍生

然後賦值運算符調用你的基地

的非工會 類X的隱式定義的複製/移動賦值運算符執行按成員禁止複製/移動其子對象的分配。 首先指定X的直接基類,按其在基指定符列表中的 聲明的順序,然後按照它們的 聲明的順序分配X的非靜態數據成員的即時 在類定義中。

1

賦值運算符是特殊成員函數之一。如果你自己沒有提供,那麼編譯器會通過分配基礎和成員來爲你生成一個。如果任何基地沒有分配操作員,則會生成一個分配操作員。

您的問題是您已經聲明BaseA的賦值運算符,但尚未提供定義。因爲它被聲明瞭,所以編譯器不會爲你生成一個,但它會嘗試調用它來複制BaseA子對象。鏈接器將無法找到定義。

請注意,對於轉讓的具體情況,繼承基本實現並沒有什麼意義。如果使用了這種情況,只要有一個基地有一個分配操作員,對象的其餘部分就不會是分配給。在大多數情況下,操作的語義將被打破。