【问题标题】:Why my virtual assignment operator not doing as intended?为什么我的虚拟赋值运算符没有按预期执行?
【发布时间】:2021-09-15 18:23:38
【问题描述】:
    class Base{
       public:
       virtual Base& operator=( const Base& ) {
          std::cout << "Base::operator=( const Base& )" << std::endl;
          return *this;
       }
    };

    class Derived: public Base{
       public:
       virtual Derived& operator=( const Base& ) {
          std::cout << "Derived::operator=( const Base& )" << std::endl;
          return *this;
       }
       virtual Derived& operator=( const Derived& ) {
          std::cout << "Derived::operator=( const Derived& )" << std::endl;
          return *this;
       }
    };

    int main(){
        Derived obj1, obj2;
        Base& ba=obj2;
        obj1=ba;//outputs[1]: Derived::operator=( const Base&)

        Derived& de=obj2;
        obj1=de;//outputs[2]: Derived::operator=( const Derived& )

        Base& bb=obj2;
        bb=obj1; //outputs[3]: Derived::operator=( const Base&)
     }

我对案例 3 输出感到困惑,赋值运算符不应该将正确的操作数作为函数参数,以便将 obj1 作为参数,并且由于 obj1 是 Derived 的类类型,所以会调用 Derived::operator=( const Derived& )?

对于输出[3],为什么输出是Derived::operator=(const Base&),而不是Derived::operator=(const Derived&)

【问题讨论】:

  • 签名不匹配。
  • 你在调用bb.operator=(obj1); 在编译时会进行名称查找和重载解析以找到合适的重载;唯一的候选人是Base::operator=(const Base&amp;)。在运行时,将调用最派生类中该方法的覆盖——即Derived::operator=(const Base&amp;)。您正在寻找双重调度; C++ 不直接支持它。
  • @Igor 也许值得正式回答?这实际上是一个非常有趣的场景。
  • 相关问题here.

标签: c++ polymorphism virtual-functions assignment-operator


【解决方案1】:

Derived::operator=( const Derived&amp; ) 在 Base 类中没有覆盖候选对象。我建议在每个旨在覆盖基类行为的方法之后添加 override 关键字。它没有任何成本,并且可以使您的代码更加安全。

如果要调用Derived::operator=( const Derived&amp; ),需要在基类中提供正确的方法签名:

class Derived; // forward declaration

class Base{
       public:
       virtual Base& operator=( const Base& ) {
          std::cout << "Base::operator=( const Base& )" << std::endl;
          return *this;
       }

       virtual Base& operator=( const Derived& ) {
          std::cout << "Base::operator=( const Derived& )" << std::endl;
          return *this;
       }
    };

class Derived: public Base{
    public:
    virtual Derived& operator=( const Base& ) override {
      std::cout << "Derived::operator=( const Base& )" << std::endl;
      return *this;
    }
    virtual Derived& operator=( const Derived& ) override {
      std::cout << "Derived::operator=( const Derived& )" << std::endl;
      return *this;
    }
};

【讨论】:

    猜你喜欢
    • 2017-12-10
    • 2021-02-28
    • 2010-10-14
    • 2011-11-14
    • 2013-05-06
    • 2012-09-20
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多