赋值运算符继承

Assignment operator inheritance

本文关键字:继承 赋值运算符      更新时间:2023-10-16

有这段代码:

#include <iostream>
class Base {
public:
    Base(){
        std::cout << "Constructor base" << std::endl;
    }
    ~Base(){
        std::cout << "Destructor base" << std::endl;
    }
    Base& operator=(const Base& a){
        std::cout << "Assignment base" << std::endl;
    }
};
class Derived : public Base{
public:
};
int main ( int argc, char **argv ) {
    Derived p;
    Derived p2;
    p2 = p;
    return 0;
}

通过 g++ 4.6 编译后的输出:

Constructor base
Constructor base
Assignment base
Destructor base
Destructor base
为什么基类的赋值运算符叫赋值

运算符,据说赋值运算符不是继承的?

实际上

,所谓的是隐式定义的Derived operator =。编译器提供的定义反过来调用Baseoperator =,您会看到相应的输出。构造函数和析构函数也是如此。当您将其留给编译器来定义operator =时,它会按如下方式定义它:

Derived& operator = (const Derived& rhs)
{
    Base1::operator =(rhs);
    ...
    Basen::operator =(rhs);
    member1 = rhs.member1;
    ...
    membern = rhs.membern; 
}

其中Base1,...,Basen是类的基(按在继承列表中指定它们的顺序(,member1, ..., membern是派生的成员(不计算继承的成员(,顺序在类定义中声明它们。

您也可以使用"using":

class Derived : public Base{
public:
    using Base::operator=;
};

http://en.cppreference.com/w/cpp/language/using_declaration

在有人帮助我之前,我读了好几遍这篇文章。

您没有默认值

Derived& operator=(const Base& a);

在你的Derived课上。

但是,将创建一个默认赋值运算符:

Derived& operator=(const Derived& a);

这将从 Base 调用赋值运算符。因此,这不是继承赋值运算符的问题,而是通过派生类中默认生成的运算符调用它的问题。

标准说(12.8(:

赋值运算符应由非静态成员实现 只有一个参数的函数。因为复制分配 运算符 operator= 如果未声明,则为类隐式声明 由用户 (12.8( 始终隐藏基类赋值运算符 通过派生类的复制赋值运算符。

然后派生调用基的赋值运算符

非联合的隐式定义的复制/移动赋值运算符 类 X 对其子对象执行成员复制/移动赋值。 X 的直接基类首先按其顺序分配 在基本说明符列表中声明,然后立即 X 的非静态数据成员按其分配顺序 在类定义中声明。

这是因为创建的默认赋值运算符调用它的基本赋值运算符,即它不是继承的,但仍作为默认赋值运算符的一部分调用。

值运算符确实不是继承的。继承该运算符将使您能够将Base分配给Derived,但是Base b; p = a;将(理所当然地(无法编译。

发生的情况是编译器生成一个operator=,因为您尚未为Derived定义自定义。自动生成的operator=将调用所有基类和所有成员的赋值运算符。在这方面,它与构造函数/析构函数非常相似,后者也调用所有基/成员上的相应函数。