这不是"When VTABLE is created?"。相反,什么时候应该初始化VPTR?它是在构造函数的开头/结尾还是在构造函数之前/之后?
A::A () : i(0), j(0) -->> here ?
{
-->> here ?
//...
-->> here ?
}
答案 0 :(得分:16)
在构建基础子对象之后和构建成员之前,在 ctor-initializer 期间设置虚拟调用的机制(通常是v表,但不一定是这样)。第[class.base.init]
条命令:
可以为正在构建的对象调用成员函数(包括虚拟成员函数,10.3)。类似地,正在构造的对象可以是
typeid
运算符(5.2.8)或dynamic_cast
(5.2.7)的操作数。但是,如果在所有 mem-initializers之前,在 ctor-initializer (或直接或间接从 ctor-initializer 中调用的函数)中执行这些操作基类完成后,操作结果未定义。
实际上,在构建基础子对象期间,存在虚函数机制,但是它是为基类设置的。部分[class.cdtor
]说:
成员函数,包括虚函数(10.3),可以在构造或销毁期间调用(12.6.2)。当从构造函数或析构函数直接或间接调用虚函数时,包括在构造或销毁类的非静态数据成员期间,以及调用所适用的对象是对象(称为{{1}在构造或破坏中,被调用的函数是最终的覆盖 在构造函数或析构函数的类中,而不是在更多派生类中重写它。如果虚函数调用使用显式类成员访问(5.2.5)并且对象表达式引用
x
的完整对象或该对象的基类子对象之一但不是x
或其中一个基类子对象,行为未定义。
答案 1 :(得分:2)
它在基类和派生类的构造函数之间初始化:
class Base { Base() { } virtual void f(); };
class Derived { Derived(); virtual void f(); };
当原始内存转换为Base对象时会发生这种情况。 在构造对象期间将Base对象转换为Derived对象时会发生这种情况。 当破坏对象时,反过来也会发生相反的情况。即每当类型改变时,vtable 指针已更改。 (我确定有人评论vtable根据标准不需要存在。)
答案 2 :(得分:0)
This msdn article explains it in great detali
它说:
“最后的答案是......正如你所期望的那样。它发生在构造函数中。”
所以..
A :: A():i(0),j(0)
{
- >>这里 !
// ...
//
}
但要小心,假设您有A类,而A类来自A。
“这是构建A1类实例时的整个事件序列:
- A1 :: A1调用A :: A
- A :: A将vtable设置为A的vtable
- A :: A执行并返回
- A1 :: A1将vtable设置为A1的vtable
- A1 :: A1执行并返回“
醇>