涉及虚函数的C++代码的输出说明

Explanation of the output of the C++ code involving virtual function

我想了解以下涉及虚函数的 C++ 程序的输出背后的原因。还请解释一下函数指针table和包含指向函数指针table的链接的虚拟指针table在以下2种情况下将如何生成,以及如何在运行时解析调用。

/******* PROGRAM 1 *******/
#include <iostream>
using namespace std;

class Car {
    public:
    virtual void foo() {
        cout<<"Car"<<endl;
    }
};

class Bmw: public Car {
    public:
    void foo1() {
        cout<<"Bmw"<<endl;
    }
};

int main() {
        Car *c = new Bmw(); 

        c->foo();           // gives output Car even though foo() 
                            //function does not exist in BMS class. 

        return 0;
}

/******* PROGRAM 2 *******/
#include<iostream>
using namespace std;

class Car {
    public:
    virtual void foo() {
        cout<<"Car"<<endl;
    }
};

class Bmw: public Car {
    public:
    void foo() {
        cout<<"Bmw"<<endl;
    }
};

class Bmw7: public Bmw {
    public:
    void foo1(){
        cout<<"Bmw7"<<endl;
    }
};

int main() {
    Car *c = new Bmw7();

    c->foo();       //gives output Bmw. Why output is not Car ??
    return 0;
}

Here 是对虚函数和虚表的很好的解释。

Every class that uses virtual functions (or is derived from a class that uses virtual functions) is given its own virtual table

Each entry in this table is simply a function pointer that points to the most-derived function accessible by that class.

这几乎可以回答您的问题。 在第一个示例中,c 可访问的最派生函数是 Carfoo。 第二个是 Bmwfoo。这里虽然你在Bmw中没有在foo前面写virtual(这不是很好的编码风格),但它的虚拟性是从Car继承的。

编辑: 正如评论中正确指出的那样,vtables 不是标准的一部分。有关更正式的解释,请参阅 this reference

For every virtual function, there is the final overrider, which is executed when a virtual function call is made. A virtual member function vf of a base class Base is the final overrider unless the derived class declares or inherits (through multiple inheritance) another function that overrides vf.