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
对象都有自己的。在这种情况下,两个类都具有函数。vptr
class
virtual
virtual
virtual
2)执行语句der d时;VPTR 如何在运行时解析?
您只是在声明der
. 但即使你调用了一个函数,在这种情况下,对任何函数的调用都会在编译时解决。仅当使用指针/引用调用函数时,才会出现虚函数解析。