有这段代码:
#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 =
。编译器提供的定义反过来调用Base
的operator =
,您会看到相应的输出。构造函数和析构函数也是如此。当您将其留给编译器来定义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=
将调用所有基类和所有成员的赋值运算符。在这方面,它与构造函数/析构函数非常相似,后者也调用所有基/成员上的相应函数。