什么时候vptr(指向vtable)被初始化为多态类?

时间:2011-07-06 05:19:39

标签: c++ constructor virtual-functions method-overriding vptr

这不是"When VTABLE is created?"。相反,什么时候应该初始化VPTR?它是在构造函数的开头/结尾还是在构造函数之前/之后?

A::A () : i(0), j(0)  -->> here ?
{
  -->> here ?
  //...
  -->> here ?
}

3 个答案:

答案 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。

  • 如果您创建一个新的A对象,则vptr将设置在A类构造函数的开头
  • 但是如果要创建一个新对象A1:
  

“这是构建A1类实例时的整个事件序列:

     
      
  1. A1 :: A1调用A :: A
  2.   
  3. A :: A将vtable设置为A的vtable
  4.   
  5. A :: A执行并返回
  6.   
  7. A1 :: A1将vtable设置为A1的vtable
  8.   
  9. A1 :: A1执行并返回“
  10.