4

As I'm currently playing with C++, I come up to an issue. Code below:

#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);
}

The comment show what output I get. The last 3 results are very much predictable, but I can't understand the first.

As shown in the second one (static_cast), Derived::operator= is called when the right operand is a Base class. However, g++ (4.5.3-r2, gentoo Linux) success to understand that it must use the 'Base' class, but doesn't go down the inheritance tree.

So I was expecting either Derived::operator= to be called, or g++ complaining for no "Derived& Derived::operator=(const Derived&)". Could someone explain this behaviour to me ? Thanks!

4

1 回答 1

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_tmpBase

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

于 2012-08-27T17:40:00.677 回答