class base {
public:
virtual void fn(){}
};
class der : public base {};
我知道编译器在类中提供了一个成员调用 VPTR,该类在运行时由构造函数使用确切的 VTABLE 进行初始化。我有 2 个问题
1) 哪个类持有 VPTR。或者所有班级都有单独的 VPTR。
2) 执行语句时der d; ,如何在运行时解析 VPTR?
class base {
public:
virtual void fn(){}
};
class der : public base {};
我知道编译器在类中提供了一个成员调用 VPTR,该类在运行时由构造函数使用确切的 VTABLE 进行初始化。我有 2 个问题
1) 哪个类持有 VPTR。或者所有班级都有单独的 VPTR。
2) 执行语句时der d; ,如何在运行时解析 VPTR?
vtable是为包含虚函数的类和从它派生的类创建的。这意味着在您的程序vtable中将为base类和类创建der。这些中的每一个vtables都将包含虚函数的地址void fn()。现在请注意,der类不包含的定义void fn(),因此它vtable包含类函数的地址。因此,如果您像base类的函数一样进行调用,则会被执行。void fn()d.fn();void fn()base
注意:虚拟表和虚拟指针是实现细节,虽然我知道的所有 C++ 编译器都使用它们,但它们不是标准强制要求的,只有结果是。
要回答您的具体问题:具有虚拟方法(它自己的或继承的)或具有(某处)虚拟继承关系的类的每个实例都需要至少一个虚拟指针。
可以有多个(当涉及虚拟继承或多继承时)。
在您的示例中,单个虚拟指针就足够了。但是,将它说成是 a 的一部分是没有意义的class。虚拟指针是实例(对象)的一部分,并且存在于类规则之外,因为这些规则适用于语言,并且虚拟指针是一种实现机制。
1) 哪个类持有 VPTR。或者所有班级都有单独的 VPTR。
如果对象是多态的(即包含函数或具有继承性) ,则每个class 对象都有自己的。在这种情况下,两个类都具有函数。vptrclassvirtualvirtualvirtual
2)执行语句der d时;VPTR 如何在运行时解析?
您只是在声明der. 但即使你调用了一个函数,在这种情况下,对任何函数的调用都会在编译时解决。仅当使用指针/引用调用函数时,才会出现虚函数解析。