简体   繁体   English

C ++中3个类的多态性

[英]Polymorphism with 3 classes in C++

The following code prints 1 2, but I would expect it to print 1 1. 以下代码打印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();
}

In my understanding, pa->f() executes B's f() function since A's is virtual, but why does pb->f() execute C's f() function when B's f() is not virtual. 根据我的理解,pa-> f()执行B的f()函数,因为A是虚拟的,但是当B的f()不是虚拟时,为什么pb-> f()执行C的f()函数。

Additionally, if I remove 'virtual' from class A, it prints 0 1, which makes sense because A and B execute their own f() functions since they aren't virtual. 另外,如果我从A类中删除'virtual',它会打印0 1,这是有道理的,因为A和B执行它们自己的f()函数,因为它们不是虚拟的。 How come pb->f() changes if it isn't affected since it's only A that changes? 如果pb-> f()没有受到影响,怎么会改变,因为只有A会发生变化?

but why does pb->f() execute C's f() function when B's f() is not virtual. 但是当B的f()不是虚拟的时候,为什么pb-> f()执行C的f()函数。

Because the dynamic type of pb is C and C::f is indeed virtual. 因为pb的动态类型是CC::f确实是虚拟的。 When you declare 当你申报时

virtual void f();

in the base class, every other void f() of the derived classes in the hierarchy is also virtual, as per §10.3/2: 在基类中,层次结构中派生类的每个其他void f()也是虚拟的,如§10.3/ 2所示:

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref- qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides112 Base::vf. 如果虚拟成员函数vf在类Base和Derived类中声明, 直接或间接从Base派生,则具有相同名称的成员函数vf,parameter-type-list(8.3.5),cv-qualification和声明了Base :: vf的ref-限定符(或不存在),然后Derived :: vf也是虚拟的(无论是否如此声明)并且它覆盖了112 Base :: vf。

(emphasis mine) (强调我的)

In fact: 事实上:

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; }
};

is equivalent to your code. 相当于你的代码。 It just so happens that the C++ standard allows virtual to be omitted in those cases. 碰巧的是,C ++标准允许在这些情况下省略virtual

这是因为在子类中编写虚拟关键字不是必需的,它只是提高了可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM