C++中3个类的多态性

mze*_*e99 3 c++

以下代码打印1 2,但我希望它打印1 1.

#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();
}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,pa-> f()执行B的f()函数,因为A是虚拟的,但是当B的f()不是虚拟时,为什么pb-> f()执行C的f()函数.

另外,如果我从A类中删除'virtual',它会打印0 1,这是有道理的,因为A和B执行它们自己的f()函数,因为它们不是虚拟的.如果它没有受到影响,pb-> f()会如何变化,因为只有A会发生变化?

Sho*_*hoe 10

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

因为动态类型pbC并且C::f确实是虚拟的.当你申报时

virtual void f();
Run Code Online (Sandbox Code Playgroud)

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

如果虚拟成员函数vf在类Base和Derived类中声明,直接或间接从Base 派生,则具有相同名称的成员函数vf,parameter-type-list(8.3.5),cv-qualification和声明了Base :: vf的ref-限定符(或不存在),然后Derived :: vf也是虚拟的(无论是否如此声明)并且它覆盖了112 Base :: 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; }
};
Run Code Online (Sandbox Code Playgroud)

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