赋值运算符继承

时间:2012-02-06 14:19:41

标签: 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;
}

g ++ 4.6编译后的输出:

Constructor base
Constructor base
Assignment base
Destructor base
Destructor base

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

6 个答案:

答案 0 :(得分:34)

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

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

其中Base1,...,Basen是类的基础(按照在继承列表中指定它们的顺序),member1, ..., membern是Derived的成员(不包括继承的成员),按顺序排列在类定义中声明它们。

答案 1 :(得分:24)

您还可以使用&#34;使用&#34;:

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

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

在有人帮我解决这个问题之前,我已经好几次看了这篇文章。

答案 2 :(得分:17)

您没有默认

Derived& operator=(const Base& a);

Derived课程中。

但是,创建了默认赋值运算符:

Derived& operator=(const Derived& a);

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

答案 3 :(得分:7)

标准说(12.8):

  

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

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

  

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

答案 4 :(得分:-1)

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

答案 5 :(得分:-1)

分配运算符确实没有继承。继承该运算符将使您能够将Base分配给Derived,但Base b; p = a;将(正确地)无法编译。

由于您尚未为operator=定义自定义格式,因此编译器会生成Derived。自动生成的operator=将调用所有基类和所有成员的赋值运算符。在这方面,它与构造函数/析构函数非常相似,它们也在所有基础/成员上调用相应的函数。