在许多源中,书籍等都是“不要调用它->子类构造函数中的虚拟函数”,并且在某些来源中解释了为什么不能这样做。因为在构建的时候,类根本没有被创建。因此,从子构造函数调用的虚拟函数将是基类的函数。这意味着在子构造函数体中,该类的VPTR指向基VTABLE。
所以我的问题是,
当子类的VPTR被覆盖到它的虚拟表上时,对象构造的时刻是什么时候?我猜一些自动生成的代码会在构造函数体的末尾或构造函数体执行之后执行。
第二个问题是,
为什么VPTR在施工结束时会过度使用?也许是因为它有一些重要的原因?为什么不能在开始构造函数体或基类构造之后重写VPTR?
Child::Child() :
Base()
//<----- Why not here?
//members initialization
{
//<----- Why not here?
//code
}发布于 2014-12-04 14:42:31
在许多来源中,书籍等都写成“不要调用这个->子类构造函数中的虚拟函数”。
我怀疑这一点。通常建议不要从基类构造函数调用虚拟函数,以避免混淆,如果您期望它们调用最终重写,而不是基类版本。如果它们是纯虚拟的,那么当然不能从基类中调用它们--这就产生了未定义的行为。
在派生类构造函数中,它们是定义良好的,可以执行您期望的操作。
因此,从子构造函数调用的虚拟函数将是基类的函数。
不,在子构造函数的主体中,动态类型是Child,虚拟函数调用将使用Child覆盖。
当子类的VPTR被覆盖到它的虚拟表上时,对象构造的时刻是什么时候?
在所有基类构造函数完成之后,以及在初始化子类成员之前。Child成员函数(包括虚拟函数)可以从成员初始化程序(但不是基类初始化程序)或构造函数体调用。
您需要小心地从成员初始化器中调用它们,因为它们可能访问未初始化的成员。但是在构造函数体中,所有基本对象和成员都是初始化的,因此它们是相当安全的。
为什么VPTR在施工结束时会过度使用?
它不是,它发生在您用<----- Why not here?表示的第一点。
发布于 2014-12-04 14:35:04
我不同意你过于简化的理由,为什么你不应该调用一个虚拟函数。首先,VTABLE实际上不是由C++标准定义的,实际上是特定于实现的:
When is VTable in C++ created?
标准允许从构造函数调用虚拟函数,实际上应该在该级别的层次结构中正确调用(但有一些限制)。
C++ constructors: why is this virtual function call not safe? http://www.parashift.com/c%2B%2B-faq-lite/calling-virtuals-from-ctors.html
然而,有很多很多原因不这样做。
https://stackoverflow.com/questions/27296421
复制相似问题