I'm trying to understand how method overrides work when the to-be-overridden method is called from a constructor.
(Using VS2012)
Given the test program:
#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;
}
I get the following output:
Creating Foo
Foo::Foo()
Foo::Initialize()
Creating Bar
Foo::Foo()
Foo::Initialize()
Bar::Bar()
I would expect the second section to be:
Creating Bar
Foo::Foo()
Foo::Initialize()
Bar::Initialize() <---- Not called.
Bar::Bar()
I'd expect that, when the Foo
ctor is called, and it calls ::Initialize()
, that the override Bar::Initialize()
is actually called.
Now, I can guess why this is happening: When Foo::Foo()
is called, before the body of Bar::Bar()
is executed, there's no guarantee that items needed by Bar::Initialize()
have been allocated, much less initialized.
The Question
Can I override a method that is called by a base constructor, and have that override execute when instantiating a derived class? That is, is there any way to modify the above code so that Bar::Initialize()
will be called?
The alternative I'm using at the moment is to remove the ::Initialize()
from the Foo
constructor, and do something like this:
Bar bar;
bar.Initialize();
and modify Bar::Initialize()
to
void Bar::Initialize() override {
Foo::Initialize();
///... bar-specific initialization here
}
Is this the best or only way to do this?