【问题标题】:Can someone explain this behaviour for virtual function?有人可以解释虚拟功能的这种行为吗?
【发布时间】:2012-04-01 14:33:31
【问题描述】:

我知道虚函数和运行时调用的基本概念。但我试过了 运行一些让我困惑的代码

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

   class B : public A {
   public:
      B& operator=(char) {
        cout << "B& B::operator=(char)" << endl;
        return *this;
      }

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

   int main() {
    B b1;
    B b2;
    A* ap1 = &b1;
    A* ap2 = &b1;
    *ap1 = 'z';
    *ap2 = b2; 
   }

运行这个程序给我以下输出:-

   A& A::operator=(char)  //expected output
   A& A::operator=(const A&) //Why this Output?  in case of  *ap2 = b2;

b2B 类型的对象,但它仍然是虚拟的 A&amp; operator=(const A&amp;) 而不是虚拟的B&amp; operator=(const B&amp;)。为什么会这样?

【问题讨论】:

    标签: c++ copy-constructor


    【解决方案1】:

    因为virtual B&amp; operator=(const B&amp;) 不会覆盖virtual A&amp; operator=(const A&amp;);论据不同。

    【讨论】:

    • Chalesworth 那么在函数调用期间指针类型很重要,而不是指针指向的对象类型,在虚函数的情况下实际上会发生这种情况吗?因为这里 ap2 是 A 的指针类型但指向 B 类型的对象?我哪里错了?
    • @Ritesh:*ap2 = b2 行中,*ap2 的编译时类型为A。所以编译器只能考虑A呈现的接口中存在的(虚拟)成员函数。
    【解决方案2】:

    派生类函数要覆盖基类函数,派生类函数需要具有完全相同的函数原型(例外:允许协变返回类型)。

    这里的派生类B中的=运算符与基类A中的=的函数原型不同,因此它不会覆盖基类=

    唯一可用的= 运算符是被调用的那个。

    【讨论】:

      【解决方案3】:

      对于被认为是重写的函数,签名必须与基类中的版本完全匹配(好吧,如果返回指针或引用,则返回类型可能是协变的)。也就是说,您需要定义

      B& B::operator= (A const&)
      

      从基类覆盖版本。请注意,对于覆盖函数中的输入参数,协变是没有意义的,因为您不能保证在仅使用基类的上下文中使用派生对象调用基类版本。如果覆盖函数的任何参数可以是逆变的,但 C++ 不支持这一点。

      【讨论】:

        【解决方案4】:

        在派生类中,函数采用 B,而在基类中采用 A。因此,基本上它不会被覆盖,因为函数参数不同。

        另请注意,在覆盖情况下的返回类型可能会有所不同,因为在您的情况下,您将返回基址中的 A 引用和派生中的 B 引用。 虚拟基数& func(const Base&) virtual Derived& func(const Base&) 这是覆盖的有效形式

        【讨论】:

          猜你喜欢
          • 2016-09-18
          • 2013-11-30
          • 1970-01-01
          • 1970-01-01
          • 2021-12-11
          • 1970-01-01
          • 2020-02-23
          • 2019-12-06
          • 1970-01-01
          相关资源
          最近更新 更多