下面的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
以便它的子類使用這個操作符?
我不確定這個錯誤與您的問題有何關係。你得到這個錯誤是因爲你聲明瞭這個函數,但從來沒有定義它。 – 2013-04-24 03:56:53
由於您只聲明瞭BaseA&operator =',因此編譯器非常正確。將其更改爲'BaseA&operator =(const BaseA&rhs)= default;'並且它會很愉快地編譯。 – Yuushi 2013-04-24 03:58:19
鏈接器不應該關心它沒有被定義,因爲它永遠不會被調用。它會被調用的唯一原因是編譯器正在生成它自己的Derived :: operator =(const Derived&)函數。 – Shum 2013-04-24 04:01:06