可能是一个简单的问题。我注意到了一些类似的问题,但它们似乎都没有解决我的问题,因此我的帖子。
Base.h:
class Base
{
public:
Base();
protected:
virtual void Create() {}
};
Base.cpp:
Base::Base()
{
Create();
}
Child.h:
class Child : public Base
{
protected:
void Create() override;
};
Child.cpp:
void Child::Create()
{
// Work happens here
}
当我创建Create
时,会在Base
而不是Child
上调用 Child
。为什么Create
没有调用Child
?
答案 0 :(得分:5)
当您从基类的ctor调用虚方法时,将调用基类的虚方法。这就是语言的定义方式。有这样的理由,如:
void Child::Show()
{
// Work that requires data fields of derived class.
}
如果要从基类的ctor调用派生类中的Show
,Child::Show
将使用Child
的数据字段,但派生类的ctor尚未调用。< / p>
还有其他相关点值得注意。想象:
class Base // The class is abstract.
{
public:
Base() { Show(); }
protected:
virtual void Show() = 0;
};
class Child : public Base
{
protected:
void Show() override { /* Some work */ }
};
在这种情况下,当您创建Child
的任何实例时,程序将简单地崩溃,因为尚未实例化纯虚方法。这将在以后完成,当Child
的ctor的隐藏部分将起作用时。 ctor的这个隐藏部分修改了对象的VMT(虚方法表)。类似的故事发生在一个复杂的物体被摧毁时。 VMT可以多次修改,具体取决于基类链的复杂性。
答案 1 :(得分:2)
物体是从头开始构建的
当您尝试从Create
的构造函数中调用Base
(以及其他成员函数)时,它会获取由给定静态类型提供的 right 定义,即是Base
换句话说,不要依赖构造函数中的虚拟成员函数。
答案 2 :(得分:2)
构造者很特别。当你在构造函数中时,派生类尚未构造,因此它实际上不存在 - 构造函数首先执行,第二个执行。您从基类构造函数调用的任何成员都将调用基类成员。