首先,我想明确一点,我知道C++标准中没有虚函数表和虚函数指针的概念。然而,我认为几乎所有的实现都以非常相似的方式实现了虚函数调用机制(如果我错了,请纠正我,但这不是主要问题)。此外,我相信我知道虚函数如何工作,也就是说,我可以总是知道哪个函数将被调用,我只需要实现细节。
假设有人问我以下问题:
"你有一个带有虚函数v1、v2、v3的基类B和一个派生类D:B,它覆盖了函数v1和v3并添加了一个虚函数v4。请解释虚调度的工作原理。"
我的回答如下:
对于每个具有虚函数的类(在本例中为B和D),我们有一个单独的指向函数的指针数组,称为虚函数表。
B的虚函数表将包含
&B::v1
&B::v2
&B::v3
D的虚函数表将包含以下内容
&D::v1
&B::v2
&D::v3
&D::v4
现在类B包含一个成员指针vptr。D自然继承它,因此也包含它。在B的构造函数和析构函数中,B将vptr设置为指向B的虚表。在D的构造函数和析构函数中,D将其设置为指向D的虚表。对于多态类X的对象x上的任何虚函数f的调用都被解释为对x.vptr[f在虚表中的位置]的调用。
问题如下:
1. 上述描述是否有错误?
2. 编译器是如何知道f在虚表中的位置的(详细说明)?
3. 这是否意味着如果一个类有两个基类,则它有两个vptrs?在这种情况下会发生什么?(尽可能详细地描述)
4. 在一个顶部为A,中间为B、C,底部为D的菱形继承中会发生什么?(A是B和C的虚基类)
谢谢。
cleanup
定义为纯虚函数,这意味着无法调用它。 - Travis Gockel