赋值运算符继承

scd*_*dmb 19 c++ inheritance

有这个代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

g ++ 4.6编译后的输出:

Constructor base
Constructor base
Assignment base
Destructor base
Destructor base
Run Code Online (Sandbox Code Playgroud)

为什么要调用基类的赋值运算符呢?据说赋值运算符不是继承的吗?

Arm*_*yan 36

实际上,所谓的是隐式定义operator =Derived.通过依次编译器提供的定义调用operator =Base,你会看到相应的输出.构造函数和析构函数也是如此.当您将它留给编译器进行定义时operator =,它将其定义如下:

Derived& operator = (const Derived& rhs)
{
    Base1::operator =(rhs);
    ...
    Basen::operator =(rhs);
    member1 = rhs.member1;
    ...
    membern = rhs.membern; 
}
Run Code Online (Sandbox Code Playgroud)

Base1,...,Basen类的基础在哪里(按照在继承列表中指定它们的顺序),并且member1, ..., membern是在类定义中声明它们的顺序中Derived的成员(不计算被继承的成员).


小智 26

您也可以使用"使用":

class Derived : public Base{
public:
    using Base::operator=;
};
Run Code Online (Sandbox Code Playgroud)

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

在有人帮我解决这个问题之前,我曾几次阅读这篇文章.

  • 最后,有人说了.+1.另见:http://stackoverflow.com/questions/4122214/why-operator-doesnt-get-inherited-from-a-template-class (2认同)

Luc*_*ore 20

您没有默认值

Derived& operator=(const Base& a);
Run Code Online (Sandbox Code Playgroud)

在你的Derived班上

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

Derived& operator=(const Derived& a);
Run Code Online (Sandbox Code Playgroud)

这会调用赋值运算符Base.所以这不是继承赋值运算符的问题,而是通过派生类中的默认生成运算符调用它.

  • operator =是从基类继承的,因为我引用了98 c ++标准"运算符函数的继承方式与其他基类函数相同." 它刚被隐式创建的operator = for Derived类隐藏. (9认同)
  • “它刚刚被隐式创建的 operator= for Derived class 隐藏了”。就像基类有 void func(int) 而派生类有 void func(double) 一样,基类函数 void func(int) 是隐藏的。在类似的行中,基类 operator= 被派生类 operator= 隐藏。 (2认同)

Yol*_*ola 9

标准说(12.8):

赋值运算符应由具有一个参数的非静态成员函数实现.因为如果没有由用户声明(12.8),则为类隐式声明复制赋值运算符operator =,基类赋值运算符总是被派生类的复制赋值运算符隐藏.

然后赋值操作符派生调用你的基础

非联合类X的隐式定义的复制/移动赋值运算符执行其子对象的成员复制/移动分配.首先按照它们在base-specifier-list中的声明顺序分配X的直接基类,然后按照它们在类定义中声明的顺序分配X的直接非静态数据成员. .