C++ 有人能解释虚拟函数的这种行为吗?

C++ 有人能解释虚拟函数的这种行为吗?,c++,copy-constructor,C++,Copy Constructor,我了解虚函数和运行时调用的基本概念。但是我试过了 运行一些让我困惑的代码 class A { public: A& operator=(char) { cout << "A& A::operator=(char)" << endl; return *this; } virtual A& operator=(const A&) { cout << "A&

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

   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; 
   }
b2
B
类型的对象,但它仍然是虚拟
A&operator=(常量A&)

而不是虚拟的
B&operator=(常量B&)
。为什么会这样

因为
虚拟B&operator=(常量B&)
不会覆盖
虚拟A&operator=(常量A&)
;参数不同。

因为
虚拟B&运算符=(常量B&)
不重写
虚拟A&运算符=(常量A&)
;参数不同。

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

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


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

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

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


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

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

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

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

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

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

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

这里,派生类中的函数是B,而在基类中,它取a。因此,基本上它不会被函数函数不同而重写。 还请注意,重写情况下的返回类型可能不同,因为在您的情况下,您在基中返回A的引用,在派生中返回B的引用。 虚拟基和函数(常量基和) 虚拟派生函数和函数(常量基和) 这是重写的有效形式


这里,在派生类中,函数取B,而在基类中,函数取A。因此,基本上它不会被重写,因为函数参数不同

还请注意,重写情况下的返回类型可能不同,因为在您的情况下,您在基中返回A的引用,在派生中返回B的引用。 虚拟基和函数(常量基和) 虚拟派生函数和函数(常量基和) 这是重写的有效形式


Chalesworth那么,在函数调用期间,指针类型是否重要,而不是指针指向的对象的类型,这在虚函数的情况下实际发生?因为这里ap2是a类型的指针,但指向B类型的对象?我哪里错了?@Ritesh:在
*ap2=b2
行中,
*ap2
的编译时类型是
A
。因此编译器只能考虑在接口中存在的(虚)成员函数:<代码> a < /COD>。因为这里ap2是a类型的指针,但指向B类型的对象?我哪里错了?@Ritesh:在
*ap2=b2
行中,
*ap2
的编译时类型是
A
。因此编译器只能考虑在接口中存在的<>代码> a < /COD>呈现的成员函数。