【发布时间】:2014-02-17 13:44:05
【问题描述】:
我试图了解当从构造函数调用要被覆盖的方法时,方法覆盖是如何工作的。
(使用VS2012)
给定测试程序:
#include <string>
#include <iostream>
using namespace std;
struct Foo
{
Foo()
{
cout << "\tFoo::Foo()" << endl;
Initialize();
}
virtual void Initialize()
{
cout << "\tFoo::Initialize()" << endl;
}
};
struct Bar : public Foo
{
Bar() {
cout << "\tBar::Bar()" << endl;
}
void Initialize() override
{
cout << "\tBar::Initialize()" << endl;
}
};
int main(int argc, char *argv[])
{
cout << "Creating Foo" << endl;
Foo foo;
cout << endl;
cout << "Creating Bar" << endl;
Bar bar;
std::getchar();
return 0;
}
我得到以下输出:
Creating Foo
Foo::Foo()
Foo::Initialize()
Creating Bar
Foo::Foo()
Foo::Initialize()
Bar::Bar()
我希望第二部分是:
Creating Bar
Foo::Foo()
Foo::Initialize()
Bar::Initialize() <---- Not called.
Bar::Bar()
我希望,当调用 Foo ctor 并调用 ::Initialize() 时,实际上会调用覆盖 Bar::Initialize()。
现在,我可以猜到为什么会发生这种情况了:当Foo::Foo() 被调用时,在Bar::Bar() 的主体被执行之前,并不能保证Bar::Initialize() 需要的项目已经被分配,更不用说初始化了。
问题
我能否覆盖由基构造函数调用的方法,并在实例化派生类时执行该覆盖?也就是有什么办法可以修改上面的代码,让Bar::Initialize()被调用?
我目前使用的替代方法是从 Foo 构造函数中删除 ::Initialize(),然后执行以下操作:
Bar bar;
bar.Initialize();
并将Bar::Initialize()修改为
void Bar::Initialize() override {
Foo::Initialize();
///... bar-specific initialization here
}
这是最好的还是唯一的方法?
【问题讨论】:
标签: c++ inheritance c++11 overriding