由于我目前正在玩C ++,我遇到了一个问题。代码如下:
#include <iostream>
class Base {
public:
virtual ~Base() {}
virtual Base& operator=(const Base& o)
{
std::cout << "Base operator called" << std::endl;
return *this;
}
};
class Derived : public Base {
public:
virtual ~Derived() {}
virtual Base& operator=(const Base& o)
{
std::cout << "Derived operator called" << std::endl;
return *this;
}
};
int main(void)
{
Derived a;
Derived b;
Base& c = a;
Base& d = b;
a = b; // Base called
a = static_cast<Base>(b); // Derived called
a = d; // Derived called
c = d; // Derived called
return (0);
}
评论显示我得到了什么输出。 最后3个结果是非常可预测的,但我无法理解第一个结果。
如第二个(static_cast)所示,当右操作数是Base类时,将调用Derived :: operator =。但是,g ++(4.5.3-r2,gentoo Linux)成功地理解它必须使用'Base'类,但不会继承继承树。
所以我期待调用Derived :: operator =,或者g ++抱怨没有“Derived&amp; Derived :: operator =(const Derived&amp;)”。有人可以向我解释这种行为吗? 谢谢!
答案 0 :(得分:3)
在operator=(Derived &)
课程中有一个编译器生成副本分配,即Derived
,因为Derived::operator=(Base const&)
不副本 - Derived
的作业。如果您在代码中使用赋值,则不会阻止编译器生成复制赋值。
所以这一行:
a = b; // Base called
为operator=(Derived &)
类调用编译器生成的Derived
,然后调用operator=(Base const&)
。因此打印Base called
。
实验:将其添加到Derived
类:
Derived & operator=(Derived const & obj) : Base(obj)
{
std::cout << "copy-assignment called" << std::endl;
return *this;
}
现在,a=b
将导致打印出来:
基地叫做
副本分配称为
请注意打印的订单。
希望澄清你的疑问。
现在这个,
a = static_cast<Base>(b); /// Derived called
在功能上等同于:
Base ___generated_tmp = static_cast<Base>(b);
a = ___generated_tmp;
表示a = ___generated_tmp
调用operator=(Base const&)
,因为___generated_tmp
的类型为Base
。
其他两个都非常清楚,正如你似乎已经知道的那样。