有这段代码:
#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
为什么要调用基类的赋值运算符呢?据说赋值运算符不是继承的吗?
答案 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=
将调用所有基类和所有成员的赋值运算符。在这方面,它与构造函数/析构函数非常相似,它们也在所有基础/成员上调用相应的函数。