调用基本运算符而不是派生的 - 正常行为?

时间:2012-08-27 17:29:59

标签: c++ inheritance virtual

由于我目前正在玩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;)”。有人可以向我解释这种行为吗? 谢谢!

1 个答案:

答案 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

其他两个都非常清楚,正如你似乎已经知道的那样。