C++ 赋值运算符继承
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9161512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Assignment operator inheritance
提问by scdmb
There is this code:
有这个代码:
#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;
}
The output after compilation by g++ 4.6:
g++ 4.6编译后的输出:
Constructor base
Constructor base
Assignment base
Destructor base
Destructor base
Why assignment operator of base class is called altough it is said that assignment operator is not inherited?
为什么要调用基类的赋值运算符,尽管说赋值运算符不是继承的?
回答by Armen Tsirunyan
Actually, what is called is the implicitly defined operator =
for Derived
. The definition provided by the compiler in turn calls operator =
for the Base
and you see the corresponding output. The same is with the constructor and destructor. When you leave it to the compiler to define operator =
, it defines it as follows:
实际上,所谓的是隐式定义的operator =
for Derived
。通过依次编译器提供的定义调用operator =
了Base
,你会看到相应的输出。构造函数和析构函数也是如此。当你把它留给编译器去定义时operator =
,它定义如下:
Derived& operator = (const Derived& rhs)
{
Base1::operator =(rhs);
...
Basen::operator =(rhs);
member1 = rhs.member1;
...
membern = rhs.membern;
}
where Base1,...,Basen
are the bases of the class (in order of specifying them in the inheritance list) and member1, ..., membern
are the members of Derived (not counting the members that were inherited) in the order you declared them in the class definition.
其中Base1,...,Basen
是类的基类(按照在继承列表中指定它们的顺序)和member1, ..., membern
派生的成员(不计算被继承的成员),按照您在类定义中声明它们的顺序。
回答by Paul Thomas
You can also use "using":
您还可以使用“使用”:
class Derived : public Base{
public:
using Base::operator=;
};
http://en.cppreference.com/w/cpp/language/using_declaration
http://en.cppreference.com/w/cpp/language/using_declaration
I read this post several time before someone helped me with this.
在有人帮助我之前,我多次阅读了这篇文章。
回答by Luchian Grigore
You don't have a default
你没有默认
Derived& operator=(const Base& a);
in your Derived
class.
在你的Derived
课堂上。
A default assignment operator, however, is created:
但是,创建了默认赋值运算符:
Derived& operator=(const Derived& a);
and this calls the assignment operator from Base
. So it's not a matter of inheriting the assignment operator, but calling it via the default generated operator in your derived class.
这从 调用赋值运算符Base
。所以这不是继承赋值运算符的问题,而是通过派生类中默认生成的运算符调用它。
回答by Yola
Standard says (12.8):
标准说(12.8):
An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (12.8), a base class assignment operator is always hidden by the copy assignment operator of the derived class.
赋值运算符应由一个只有一个参数的非静态成员函数实现。因为如果用户未声明,则为类隐式声明了复制赋值运算符 operator= (12.8),所以基类赋值运算符始终被派生类的复制赋值运算符隐藏。
and then assignment operator of derived call your base
然后派生的赋值运算符调用你的基数
The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy-/move assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition.
非联合类 X 的隐式定义的复制/移动赋值运算符执行其子对象的成员复制/移动赋值。X 的直接基类首先按照它们在基类说明符列表中的声明顺序赋值,然后按照它们在类定义中声明的顺序赋值 X 的直接非静态数据成员.
回答by Cpt. Red
That is because the default assignment operator created calls it's base assignment operator, i.e. it isn't inherited but still called as part of the default assignment operator.
这是因为创建的默认赋值运算符调用它的基本赋值运算符,即它不是继承的,但仍作为默认赋值运算符的一部分调用。
回答by Grizzly
Assignment operator is indeed not inherited. Inheriting that operator would enable you to assign a Base
to a Derived
, however Base b; p = a;
will (rightfully) fail to compile.
赋值运算符确实不是继承的。继承该运算符将使您能够将 a 分配Base
给 a Derived
,但是Base b; p = a;
将(理所当然地)无法编译。
What happens is that the compiler generates an operator=
, since you haven't defined a custom one for Derived
. The autogenerated operator=
will call the assignment operators of all all base classes and all members. In that aspect it is much the same as constructors/destructors, which also call the respective function on all Bases/members.
发生的情况是编译器生成一个operator=
,因为您还没有为Derived
. 自动生成的operator=
将调用所有基类和所有成员的赋值运算符。在这方面,它与构造函数/析构函数非常相似,它们也在所有基础/成员上调用相应的函数。