这不是关于“VTABLE何时创建?”的问题。相反,VPTR应该在什么时候初始化?是在构造函数的开始/结束之前/之后?
A::A () : i(0), j(0) -->> here ?
{
-->> here ?
//...
-->> here ?
}
这不是关于“VTABLE何时创建?”的问题。相反,VPTR应该在什么时候初始化?是在构造函数的开始/结束之前/之后?
A::A () : i(0), j(0) -->> here ?
{
-->> here ?
//...
-->> here ?
}
[class.base.init]
节规定:typeid
操作符(5.2.8)或 dynamic_cast
(5.2.7)操作也是如此。但是,如果在 ctor-initializer (或在直接或间接从 ctor-initializer 调用的函数中)执行这些操作时,还没有完成所有基类的 mem-initializers ,则操作的结果未定义。”[class.cdtor]
节中提到:x
),则被调用的函数是构造函数或析构函数中的最终覆盖者,而不是在更派生类中覆盖它的函数。如果虚函数调用使用显式类成员访问(5.2.5)并且对象表达式引用x
或该对象的一个基类子对象的完整对象,但不是x
或其基类子对象之一,则行为未定义。”它在基类和派生类的构造函数之间进行初始化:
class Base { Base() { } virtual void f(); };
class Derived { Derived(); virtual void f(); };
当原始内存转换为Base对象时会发生这种情况。 在对象构造期间将Base对象转换为Derived对象时也会发生这种情况。 当销毁对象时,同样会反向发生。即每次类型更改时,虚表指针都会改变。(我确定有人会评论说根据std,虚表不需要存在。)
文章中写道:
"最终答案是...正如你所预期的那样。它发生在构造函数中。"
所以...
A::A() : i(0), j(0)
{
-->> 在这里!
//...
//
}
但要小心,假设你有一个类 A 和一个从 A 派生的类 A1。
vptr
? - fengqithis
的虚拟性进行完全内联,其中“对Info的完全内联”表示对所有可能访问Info的直接和间接调用函数进行内联,而“x的虚拟性”是指所有依赖于x的动态类型的特征或行为(特别是虚函数调用),... - curiousguythis
of base class ctors” 意味着递归地内联所有从基类构造函数调用的函数,这些函数可能在this
上调用虚函数(或使用typeid(*this)
或dynamic_cast
),从而带来了对 vptr 更改的可能优化。特别是当基类构造函数具有空体和没有非内联构造的成员对象时,它完全可以递归地内联:这种基类构造函数永远不会看到 vptr 值。 - curiousguy