是否可以继承赋值操作符?

C++: Is it possible to inherit the assignment operator?

本文关键字:赋值操作符 继承 是否      更新时间:2023-10-16

下面的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上还有其他几个类似的问题,但是它们似乎都涉及编译器自动生成调用BaseA::operator = (const BaseA&)Derived &Derived::operator = (const Derived &)函数。在这种情况下,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,使其子类使用此操作符?

不继承赋值操作符operator=。没有默认的

Derived& operator=(const BaseA& a);

创建了一个默认的赋值操作符:

Derived& operator=(const Derived& a);

,调用BaseA中的赋值操作符。所以这不是继承赋值操作符的问题,而是通过派生类中默认生成的操作符调用它的问题。还有一些注释:标准规定(12.8):

赋值操作符应由非静态成员实现只有一个参数的函数。因为拷贝赋值如果未声明操作符Operator =,则隐式地为类声明操作符对于用户(12.8),基类赋值操作符总是隐藏的通过派生类的复制赋值操作符。

然后赋值操作符调用基

用于非联合的隐式定义的复制/移动赋值操作符类X对其子对象执行按成员复制/移动赋值。首先分配X的直接基类,按照它们的顺序在基指定符列表中声明,然后是直接的X的非静态数据成员被赋值,按照它们被赋值的顺序在类定义中声明。

赋值操作符是特殊的成员函数之一。如果你自己不提供一个,编译器将通过分配基和成员来生成一个。如果任何一个基类没有赋值操作符,则生成一个赋值操作符。

您的问题是您已经为BaseA声明了赋值操作符,但没有提供定义。因为它是声明的,编译器不会为您生成一个,但它会尝试调用它来复制BaseA子对象。链接器将无法找到定义。

注意,对于赋值的特定情况,继承基本实现实际上没有意义。如果使用这种方法,只要一个基类具有赋值操作符,对象的其余部分就不会被赋值。在大多数情况下,该操作的语义将被破坏。

您可以继承基类操作符和所有其他方法,如果您不在基类中声明它-默认赋值操作符将由编译器生成,如果您声明它-当您必须提供自己的实现时,因此您将获得由于operator=未在您的BaseA类中定义而导致的错误,只有声明。