C++中3类的多态性

Polymorphism with 3 classes in C++

本文关键字:多态性 3类 C++      更新时间:2023-10-16

下面的代码打印12,但我希望它打印11。

#include <iostream>
using namespace std;
class A {
public:
    virtual void f() { cout << "0" << endl; }
}; 
class B : public A{
public:
    void f() { cout << "1" << endl; }
};
class C : public B{
public:
    void f() { cout << "2" << endl; }
};
int main() {
    A *pa = new B();
    B *pb = new C();
    pa->f();
    pb->f();
}

在我的理解中,pa->f()执行B的f()函数,因为A是虚拟的,但为什么pb->f(。

此外,如果我从类A中删除"virtual",它将打印0 1,这是有意义的,因为A和B执行自己的f()函数,因为它们不是虚拟的。如果pb->f()没有受到影响,为什么它会改变,因为它只是一个改变的A?

但是,当B的f()不是虚拟的时,为什么pb->f()执行C的f(()函数呢。

因为pb的动态类型是C,而C::f实际上是虚拟的。当您申报时

virtual void f();

根据§10.3/2:,在基类中,层次结构中派生类的每个其他void f()也是虚拟的

如果虚拟成员函数vf在基类和Derived类中声明,直接或间接地从基类派生,则声明与Base::vf具有相同名称、参数类型列表(8.3.5)、cv限定符和ref-限定符(或不存在相同限定符)的成员函数vf,则Derived::vf也是虚拟的(无论是否如此声明),并且它覆盖了112Base::vf。

(重点矿井)

事实上:

class A {
public:
    virtual void f() { cout << "0" << endl; }
}; 
class B : public A{
public:
    virtual void f() { cout << "1" << endl; }
};
class C : public B{
public:
    virtual void f() { cout << "2" << endl; }
};

相当于您的代码。恰好C++标准允许在这些情况下省略virtual

之所以会发生这种情况,是因为在子类中编写虚拟关键字是不必要的,它只是提高了可读性。