C++ 11 Delegated Constructor Pure Virtual Method & Function Calls -- Dangers? - c++

Not a Duplicate of Invoking virtual function and pure-virtual function from a constructor:
Former Question relates to C++ 03, not new Constructor Delegation behavior in C++ 11, and the question does not address the mitigation of undefined behavior by using delegation to ensure proper construction before pure virtual implementations are executed.
In C++ 11, what are the dangers of invoking Pure Virtual functions in a class' constructor, during construction, but after the class/object has been "fully constructed" via constructor delegation?
Apparently, somewhere in the C++ 11 spec such a constraint exists,
Member functions (including virtual member functions, 10.3) can be
called for an object under construction. Similarly, an object under
construction can be the operand of the typeid operator ..
- 12.6.2 #13 of the [C++ Working Draft] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf)
Can't find "Fair Use" version of Published Spec.
C++11 considers an object constructed once any constructor finishes
execution. Since multiple constructors will be allowed to execute,
this will mean that each delegate constructor will be executing on a
fully constructed object of its own type. Derived class constructors
will execute after all delegation in their base classes is complete.
- Wikipedia saying that this is a C++ 11 thing.
Actual C++ 11 Reference unknown.
Following Example Compiles AND RUNS in Nov CTP of Visual Studio 2012 C++ Compiler:
#include <string>
/**************************************/
class Base
{
public:
int sum;
virtual int Do() = 0;
void Initialize()
{
Do();
}
Base()
{
}
};
/**************************************/
// Optionally declare class as "final" to avoid
// issues with further sub-derivations.
class Derived final : public Base
{
public:
virtual int Do() override final
{
sum = 0 ? 1 : sum;
return sum / 2 ; // .5 if not already set.
}
Derived(const std::string & test)
: Derived() // Ensure "this" object is constructed.
{
Initialize(); // Call Pure Virtual Method.
}
Derived()
: Base()
{
// Effectively Instantiating the Base Class.
// Then Instantiating This.
// The the target constructor completes.
}
};
/********************************************************************/
int main(int args, char* argv[])
{
Derived d;
return 0;
}

With the updates, the example code looks okay to me, with the caveat that if you ever make a subclass of Derived, the subclass's override of Do() won't get called by Derived(const std::string &), rather Derived::Do() will still get called; which might not be what you wanted. In particular, when Initialize() is called from the Derived(const std::string &) constructor, the object is still "only" a Derived object and not a SubDerived object yet (because the SubDerived layer of construction-code hasn't started yet) and that is why Derived::Do() would be called and not SubDerived::Do().
Q: What if the subclass uses the same delegation pattern to ensure everything is instantiate in the same way?
A: That would mostly work, but only if it's okay for Derived::Do() to be called before SubDerived::Do() is called.
In particular, say you had class SubDerived that did the same things as Derived does above. Then when the calling code did this:
SubDerived foo("Hello");
the following sequence of calls would occur:
Base()
Derived()
Derived(const std::string &)
Base::Initialize()
Derived::Do()
SubDerived()
SubDerived(const std::string &)
Base::Initialize()
SubDerived::Do()
... so yes, SubDerived::Do() would eventually get called, but Derived::Do() would have been called also. Whether or not that will be a problem depends on what the various Do() methods actually do.
Some advice: Calling virtual methods from within a constructor is usually not the best way to go. You might want to consider simply requiring the calling code to call Do() manually on the object after the object is constructed. It's a bit more work for the calling code, but the advantage is that it you can avoid the not-very-obvious-or-convenient semantics that come into play when doing virtual method calls on partially-constructed objects.

In a typical single-constructor inheritance scenario, it is UB to call a pure virtual function in the base constructor:
[C++11: 10.4/6]: Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.
struct Base
{
Base()
{
foo(); // UB
}
virtual void foo() = 0;
};
struct Derived : Base
{
virtual void foo() {}
};
There is no exemption here for such a call being made in a delegated constructor call, because at this point the more-derived part of the object still hasn't been constructed.
struct Base
{
Base()
{
foo(); // still UB
}
Base(int) : Base() {};
virtual void foo() = 0;
};
struct Derived : Base
{
virtual void foo() {}
};
Here's the Wikipedia passage that you cited:
C++11 considers an object constructed once any constructor finishes execution. Since multiple constructors will be allowed to execute, this will mean that each delegate constructor will be executing on a fully constructed object of its own type. Derived class constructors will execute after all delegation in their base classes is complete.
The key is the second bolded sentence, rather than the first, as one may misconstrue from a quick glance.
However, your posted code snippet is fine, and that's because the derived constructor body is undergoing execution, not the constructor for the abstract class, which has already been completely constructed. That said, the fact that you've had to ask for proof that it's safe should be some indication that this is not the most expressive or intuitive approach, and I would try to avoid it in your design.

Related

Problem with abstract class inheritance and constructor at C++

class Base {
public:
Base(int a) : a_(a) {
//do something
someMethod();
//do something else
};
protected:
int a_;
virtual void someMethod() = 0 {};
};
class Derived : Base {
public:
Derived() {
Base::Base(42);
}
protected:
void someMethod() override {
//realisation
}
};
int main() {
Derived *obj = new Derived();
delete obj;
}
This code doesn't work by two mistakes: base class's default constructor is needed and base class's constructor with parameters can't be called because of using abstract methods
My problem is that someMethod() realised in class Derived is not called at all when I create object of class Derived. Also I don't want to use default constructor of class Base, but compiler is swearing.
How can I correct my code to see functionality that I want?
How can I correct my code to see functionality that I want?
Remove the call to a pure virtual function in the constructor of Base.
Call someMethod in the constructor of the derived class that overrides it instead.
Provide an initialiser to the Base subobject in the member initiliser list. If you don't provide an initialiser to the base, it will be default initialised.
Why this cannot work ?
This design will not work because of the way obects are constructed.
When you construct a Derived, the first thing happening is that a Base object is constructed with a Base constructor. There is no Derived object at this moment, so if you'd invoke the virtual function in the Base constructor, it would be the virtual that would be valid for the Base class until you leave the Base constructor's body.
This is allowed by the standard, but with restrictions:
[base.class.init]/16: Member functions (including virtual member functions) can be called for an object under construction. (...) However,
if these operations are performed in a ctor-initializer (or in a
function called directly or indirectly from a ctor-initializer) before
all the mem-initializers for base classes have completed, the program
has undefined behavior.
These restriction do not apply to virtual functions that are called from the constructor body, since the body is executed after all initializers.
But in your case the virtual function is pure virtual for the Base. So it's UB according to the following clause:
[class.abstract]/6: Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making
a virtual call to a pure virtual function directly or
indirectly for the object being created (or destroyed) from such a
constructor (or destructor) is undefined.
What is the alternative
There is unfortunately no other real alternative than using a two step initialization in which you first construct the object and then call an initialization function before using the object.
The only issue with this approach is the risk of forgetting the call to the initialization function. You can protect you against this:
using a flag to indicate if the intialization has taken place and check this flag in all member functions (yes, it's a little overhead).
if you have an abstract class, you may perhaps use a factory pattern (factory method or abstract factory). You could then let the factory do the call.
you may use the builder pattern, and make sure that the constructor is only visible to the builder who won't forget the initialization either.
Other problems with your code
You must be careful about how you "call" the base constructor from the derived constructor:
class Derived : Base {
public:
Derived() : Base(42) // this is the correct place !
{
//Base::Base(42); //<==== OUCH !!! NO !! This creates a temporary base object !!
}
...
};
You'd also need to be careful about the pure virtuals (I don't know if it's a typo or if your compiler could compile your code):
virtual void someMethod() = 0; // if it's abstract, no pending {} !

Dynamic binding inside constructor for virtual Function in C++

As per the standard, we know that constructor always go for an early binding of a virtual function inside them because they don't have complete idea the derived class hierarchy downside.
In this case if early binding is used inside my base constructor, I have passed a derived object to a base class pointer which is completely acceptable (an upcasting is done here). If early binding is used the selection of the virtual function should be based on the type of the pointer (which is Base * here) but not the content of the pointer(the object pointed by the pointer because we don't know the exact object being pointed). In that case since the pointer type is Base * we should have invoked only Base class virtual function in both cases. Could some one please clarify this?
I think dynamic binding is used here rather than early binding. Please correct me if my understanding is wrong.
The first line of the output which invokes base is completely fine
class Base
{
public:
Base(){
fun();
}
Base(Base *p)
{
p->fun();
}
virtual void fun()
{
cout<<"In Base"<<endl;
}
};
class Derived : public Base
{
public:
void fun()
{
cout<<"In Derived"<<endl;
}
};
int main()
{
Derived d;
Base b(&d);
}
O/P :
In Base
In Derived
The rule for virtual calls within a constructor body applies to an object currently being constructed, because that object is not yet considered to be an object of any derived class. (And there's a similar rule for an object currently being destroyed.) It has little to do with "early binding" in the sense of using a compile-time type, such as the syntax ClassName::member_func() forces.
Your code has two different objects d and b, and the constructor of d has entirely finished by the time you get to the p->fun(); line.
In detail:
The program enters main.
The object d is created using the implicitly declared default constructor of Derived.
The first thing Derived::Derived() does is create the base class subobject, by calling the default constructor Base::Base().
The body of Base::Base() calls fun(). Since we have not yet entered the body of the Derived::Derived() constructor, this virtual lookup invokes Base::fun().
Base::Base() finishes.
The body of Derived::Derived(), which is empty, executes and finishes.
Back in main, the object b is created by passing a pointer to d to the constructor Base::Base(Base*).
The body of Base::Base(Base *p) calls p->fun(). Since p is a pointer to d, which is already a completely constructed object of type Derived, this virtual lookup invokes Derived::fun().
Contrast with this slightly different example, where we define a default constructor of Derived to pass this (implicitly converted to Base*) to the constructor for the Base subobject. (This is valid, though could be risky if the pointer were used in other ways, such as in an initializer for a base or member of Base.)
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public:
Base(){
fun();
}
Base(Base *p)
{
p->fun();
}
virtual void fun()
{
cout<<"In Base"<<endl;
}
};
class Derived
{
public:
Derived() : Base(this) {}
virtual void fun() override
{
cout << "In Derived" << endl;
}
};
int main()
{
Derived d;
}
This program will print just "In Base", since now in Base::Base(Base *p), p does point at the same object which is currently being constructed.
The reason is that C++ classes are constructed from Base classes to derived classes and virtual call table of the complete object is created when the object creation process is completed. Therefore, the base class function is called in the code excerpt above. Unless otherwise mandatory, you should never make virtual function calls in the constructor. Below is an excerpt from Bjarne Stroustrup's C++ Style and Technique FAQ:
In a constructor, the virtual call mechanism is disabled because
overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
Destruction is done “derived class before base class”, so virtual
functions behave as in constructors: Only the local definitions are used –
and no calls are made to overriding functions to avoid touching the (now
destroyed) derived class part of the object.

control of base constructor in derived classes, potential double-initialization

Regarding this question and the answer to it there does seem to be an exception, but it raised more questions for me than answering them. Consider this:
#include <iostream>
using namespace std;
struct base {
virtual void test() {cout << "base::test" << endl;}
base() {test();}
virtual ~base() {}
};
struct derived : base {
virtual void test() {cout << "derived::test" << endl;}
derived() : base() {}
~derived() {}
};
int main() {
derived d;
return 0;
}
I naively thought this would only print either of the two messages. It actually prints both - first the base version then derived. This behaves the same on -O0 and -O3 settings, so it's not an optimization or lack thereof as far as I can tell.
Am I to understand that calling base (or higher / earlier classes' constructors) within a derived constructor, will not prevent the default base constructor (or otherwise) from being called beforehand?
That is to say, the sequence in the above snippet when constructing a derived object is: base() then derived() and within that base() again?
I know it doesn't make sense to modify the vtable just for the purposes of calling base::base(), back to what it was before derived::derived() was called, just for the sake of calling a different constructor. I can only guess that vtable-related things are hard-coded into the constructor-chain and calling previous constructors is literally interpreted as a proper method call (up to the most-derived object having been constructed in the chain so far)?
These minor questions aside, it raises two important ones:
1. Is calling a base constructor within a derived constructor always going to incur calling the default base constructor prior to the derived constructor being called in the first place? Is this not inefficient?
2. Is there a use-case where the default base constructor, per #1, shouldn't be used in lieu of the base constructor explicitly called in a derived classes' constructor? How can this be achieved in C++?
I know #2 sounds silly, after all you'd have no guarantee the state of the base class part of a derived class was 'ready' / 'constructed' if you could defer calling the base constructor until an arbitrary function call in the derived constructor. So for instance this:
derived::derived() { base::base(); }
... I would expect to behave the same way and call the base constructor twice. However is there a reason that the compiler seems to treat it as the same case as this?
derived::derived() : base() { }
I'm not sure. But these seem to be equivalent statements as far as observed effects go. It runs counter to the idea I had in mind that the base constructor could be forwarded (in a sense at least) or perhaps a better choice of word would be selected within a derived class using :base() syntax. Indeed, that notation requires base classes to be put before members distinct to the derived class...
In other words this answer and it's example (forget for a moment its C#) would call the base constructor twice? Although I understand why it would be doing that, I don't understand why it doesn't behave more "intuitively" and select the base constructor (at least for simple cases) and call it only once.
Isn't that a risk of double-initializing the object? Or is that part-and-parcel of assuming the object is uninitialized when writing constructor code? worst case do I now have to assume that every class member could potentially be initialized twice and guard against that?
I'll end with a horrible example - but would this not leak memory? should it be expected to leak?
#include <iostream>
using namespace std;
struct base2 {
int * member;
base2() : member(new int) {}
base2(int*m) : member(m) {}
~base2() {if (member) delete member;}
};
struct derived2 : base2 {
derived2() : base2(new int) {
// is `member` leaking?
// should it be with this syntax?
}
};
int main() {
derived2 d;
return 0;
}
but would this not leak memory? should it be expected to leak?
no. The sequence of operations will be:
derived2::derived2()
auto p = new int
base2::base2(p)
base2::member = p
And for the destructor:
derived2::~derived2() (implied)
base2::~base2()
if (base2::member) { delete base2::member; }
One new, one delete. Perfect.
Don't forget to write correct assignment/copy constructors.
To construct derived class object compiler need to construct its base part. You can specify which base class constructor compiler should use by derived2() : base2(new int).
If you lack such specification, compiler will use base default constructor.
So, base constructor will be called only once, and long as your code did not cause memory leak there wouldn't be any one.

C++ Pure Virtual Initializer [duplicate]

I know that calling a virtual method from a base class constructor can be dangerous since the child class might not be in a valid state. (at least in C#)
My question is what if the virtual method is the one who initializes the state of the object ? Is it good practice or should it be a two step process, first to create the object and then to load the state ?
First option: (using the constructor to initialize the state)
public class BaseObject {
public BaseObject(XElement definition) {
this.LoadState(definition);
}
protected abstract LoadState(XElement definition);
}
Second option: (using a two step process)
public class BaseObject {
public void LoadState(XElement definition) {
this.LoadStateCore(definition);
}
protected abstract LoadStateCore(XElement definition);
}
In the first method the consumer of the code can create and initialize the object with one statement:
// The base class will call the virtual method to load the state.
ChildObject o = new ChildObject(definition)
In the second method the consumer will have to create the object and then load the state:
ChildObject o = new ChildObject();
o.LoadState(definition);
(This answer applies to C# and Java. I believe C++ works differently on this matter.)
Calling a virtual method in a constructor is indeed dangerous, but sometimes it can end up with the cleanest code.
I would try to avoid it where possible, but without bending the design hugely. (For instance, the "initialize later" option prohibits immutability.) If you do use a virtual method in the constructor, document it very strongly. So long as everyone involved is aware of what it's doing, it shouldn't cause too many problems. I would try to limit the visibility though, as you've done in your first example.
EDIT: One thing which is important here is that there's a difference between C# and Java in order of initialization. If you have a class such as:
public class Child : Parent
{
private int foo = 10;
protected override void ShowFoo()
{
Console.WriteLine(foo);
}
}
where the Parent constructor calls ShowFoo, in C# it will display 10. The equivalent program in Java would display 0.
In C++, calling a virtual method in a base class constructor will simply call the method as if the derived class doesn't exist yet (because it doesn't). So that means that the call is resolved at compile time to whatever method it should call in the base class (or classes it derived from).
Tested with GCC, it allows you to call a pure virtual function from a constructor, but it gives a warning, and results in a link time error. It appears that this behavior is undefined by the standard:
"Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (class.virtual) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined."
With C++ the virtual methods are routed through the vtable for the class that is being constructed. So in your example it would generate a pure virtual method exception since whilst BaseObject is being constructed there simply is no LoadStateCore method to invoke.
If the function is not abstract, but simply does nothing then you will often get the programmer scratching their head for a while trying to remember why it is that the function doesn't actually get called.
For this reason you simply can't do it this way in C++ ...
For C++ the base constructor is called before the derived constructor, which means that the virtual table (which holds the addresses of the derived class's overridden virtual functions) does not yet exist. For this reason, it is considered a VERY dangerous thing to do (especially if the functions are pure virtual in the base class...this will cause a pure-virtual exception).
There are two ways around this:
Do a two-step process of construction + initialization
Move the virtual functions to an internal class that you can more closely control (can make use of the above approach, see example for details)
An example of (1) is:
class base
{
public:
base()
{
// only initialize base's members
}
virtual ~base()
{
// only release base's members
}
virtual bool initialize(/* whatever goes here */) = 0;
};
class derived : public base
{
public:
derived ()
{
// only initialize derived 's members
}
virtual ~derived ()
{
// only release derived 's members
}
virtual bool initialize(/* whatever goes here */)
{
// do your further initialization here
// return success/failure
}
};
An example of (2) is:
class accessible
{
private:
class accessible_impl
{
protected:
accessible_impl()
{
// only initialize accessible_impl's members
}
public:
static accessible_impl* create_impl(/* params for this factory func */);
virtual ~accessible_impl()
{
// only release accessible_impl's members
}
virtual bool initialize(/* whatever goes here */) = 0;
};
accessible_impl* m_impl;
public:
accessible()
{
m_impl = accessible_impl::create_impl(/* params to determine the exact type needed */);
if (m_impl)
{
m_impl->initialize(/* ... */); // add any initialization checking you need
}
}
virtual ~accessible()
{
if (m_impl)
{
delete m_impl;
}
}
/* Other functionality of accessible, which may or may not use the impl class */
};
Approach (2) uses the Factory pattern to provide the appropriate implementation for the accessible class (which will provide the same interface as your base class). One of the main benefits here is that you get initialization during construction of accessible that is able to make use of virtual members of accessible_impl safely.
For C++, section 12.7, paragraph 3 of the Standard covers this case.
To summarize, this is legal. It will resolve to the correct function to the type of the constructor being run. Therefore, adapting your example to C++ syntax, you'd be calling BaseObject::LoadState(). You can't get to ChildObject::LoadState(), and trying to do so by specifying the class as well as the function results in undefined behavior.
Constructors of abstract classes are covered in section 10.4, paragraph 6. In brief, they may call member functions, but calling a pure virtual function in the constructor is undefined behavior. Don't do that.
If you have a class as shown in your post, which takes an XElement in the constructor, then the only place that XElement could have come from is the derived class. So why not just load the state in the derived class which already has the XElement.
Either your example is missing some fundamental information which changes the situation, or there's simply no need to chain back up to the derived class with the information from the base class, because it has just told you that exact information.
i.e.
public class BaseClass
{
public BaseClass(XElement defintion)
{
// base class loads state here
}
}
public class DerivedClass : BaseClass
{
public DerivedClass (XElement defintion)
: base(definition)
{
// derived class loads state here
}
}
Then your code's really simple, and you don't have any of the virtual method call problems.
For C++, read Scott Meyer's corresponding article :
Never Call Virtual Functions during Construction or Destruction
ps: pay attention to this exception in the article:
The problem would almost certainly
become apparent before runtime,
because the logTransaction function is
pure virtual in Transaction. Unless it
had been defined (unlikely, but
possible) the program wouldn't link: the linker would be unable to find the necessary implementation of Transaction::logTransaction.
Usually you can get around these issues by having a greedier base constructor. In your example, you're passing an XElement to LoadState. If you allow the state to be directly set in your base constructor, then your child class can parse the XElement prior to calling your constructor.
public abstract class BaseObject {
public BaseObject(int state1, string state2, /* blah, blah */) {
this.State1 = state1;
this.State2 = state2;
/* blah, blah */
}
}
public class ChildObject : BaseObject {
public ChildObject(XElement definition) :
base(int.Parse(definition["state1"]), definition["state2"], /* blah, blah */) {
}
}
If the child class needs to do a good bit of work, it can offload to a static method.
In C++ it is perfectly safe to call virtual functions from within the base-class - as long as they are non-pure - with some restrictions. However, you shouldn't do it. Better initialize objects using non-virtual functions, which are explicitly marked as being such initialization functions using comments and an appropriate name (like initialize). If it is even declared as pure-virtual in the class calling it, the behavior is undefined.
The version that's called is the one of the class calling it from within the constructor, and not some overrider in some derived class. This hasn't got much to-do with virtual function tables, but more with the fact that the override of that function might belong to a class that's not yet initialized. So this is forbidden.
In C# and Java, that's not a problem, because there is no such thing as a default-initialization that's done just before entering the constructor's body. In C#, the only things that are done outside the body is calling base-class or sibling constructors i believe. In C++, however, initializations done to members of derived classes by the overrider of that function would be undone when constructing those members while processing the constructor initializer list just before entering the constructors body of the derived class.
Edit: Because of a comment, i think a bit of clarification is needed. Here's an (contrived) example, let's assume it would be allowed to call virtuals, and the call would result in an activation of the final overrider:
struct base {
base() { init(); }
virtual void init() = 0;
};
struct derived : base {
derived() {
// we would expect str to be "called it", but actually the
// default constructor of it initialized it to an empty string
}
virtual void init() {
// note, str not yet constructed, but we can't know this, because
// we could have called from derived's constructors body too
str = "called it";
}
private:
string str;
};
That problem can indeed be solved by changing the C++ Standard and allowing it - adjusting the definition of constructors, object lifetime and whatnot. Rules would have to be made to define what str = ...; means for a not-yet constructed object. And note how the effect of it then depends on who called init. The feature we get does not justify the problems we have to solve then. So C++ simply forbids dynamic dispatch while the object is being constructed.

How to call a derived class method from a base class method within the constructor of base

I am wondering if it is possible to call a derived class´ function from within a function called by the base constructor (shouldn´t it already be created when the code in the brackets are executed?)
#pragma once
class ClassA
{
public:
ClassA(void);
virtual ~ClassA(void);
void Init();
protected:
short m_a;
short m_b;
virtual void SetNumbers(short s);
};
include "ClassA.h"
#include <iostream>
ClassA::ClassA(void) : m_a(0), m_b(0)
{
Init();
}
ClassA::~ClassA(void)
{
}
void ClassA::SetNumbers(short s)
{
std::cout << "In ClassA::SetNumbers()\n";
m_a = s;
m_b = s;
}
void ClassA::Init()
{
this->SetNumbers(2);
}
#pragma once
#include "ClassA.h"
class ClassB : public ClassA
{
public:
ClassB(void);
virtual ~ClassB(void);
virtual void SetNumbers(short);
int x;
};
#include "ClassB.h"
#include <iostream>
ClassB::ClassB(void)
{
}
ClassB::~ClassB(void)
{
}
void ClassB::SetNumbers(short s)
{
std::cout << "In ClassB::SetNumbers()\n";
m_a = ++s;
m_b = s;
ClassA::SetNumbers(s);
}
Any suggestions how to do it?...
Thank You in advance :)...
No. All parts of B (starting with A, as it's base) are constructed before B's constructor is called. So, by the time SetNumbers is called, no part of B (except for the A part) has been constructed --- and that may include the v-table, so there's no way to know where that call is going to go.
Of course, there is a simple solution to this: Call B::SetNumber() from within B's constructor (That is, after all, the purpose of B's constructor)
You can't do this for the simple logical reason that while the base class is being constructed, the derived class hasn't even begun to be constructed. You can't call a member function on an object that doesn't exist (yet).
In practice, even if you managed to call SetNumbers and assign to the member variables of the derived class before they were initialized they would surely be overwritten when they finally get initialized. I admit it's a bit pointless to reason about this as we would be well outside defined behaivour.
No, sorry. :( It might compile in one or two C++ compilers, but it's not recommended. From the C++ FAQ Lite section 10.7:
[10.7] Should you use the this pointer
in the constructor?
[...snip...]
Here is something that never works:
the {body} of a constructor (or a
function called from the constructor)
cannot get down to a derived class by
calling a virtual member function that
is overridden in the derived class. If
your goal was to get to the overridden
function in the derived class, you
won't get what you want. Note that you
won't get to the override in the
derived class independent of how you
call the virtual member function:
explicitly using the this pointer
(e.g., this->method()), implicitly
using the this pointer (e.g.,
method()), or even calling some other
function that calls the virtual member
function on your this object. The
bottom line is this: even if the
caller is constructing an object of a
derived class, during the constructor
of the base class, your object is not
yet of that derived class. You have
been warned.
NOTE: Emphasis mine.
More details at the link
The only time you can do this is when something is derived from a template that is parameterised by itself:
template<typename T> class base
{
T* down_cast() throw()
{
return static_cast<Derived*>(this);
}
const T* down_cast() const throw()
{
return static_cast<const Derived*>(this);
}
public:
base()
{
down_cast()->doSomething();
}
/* … */
};
class derived : private base<derived>
{
public:
void doSomething()
{
}
};
Note that doSomething is public and not virtual.
We can static_cast to derived, because it's known that derived is the derived type.
Deriving something from a base parameterised by itself is a strange thing to be doing at the best of times. It's said that when the ATL team in microsoft used it they asked the C++ compiler team if it was valid and nobody was sure, though it is valid because template construction depends on names as follows:
First the template is available, but not used in a class. Then, the name derived available. Then it instantiates the layout of base<derived> — this requires knowledge of the member variables and virtual functions, as long as none of that depends upon knowledge of derived’s layout (pointers and references are fine) this will all go okay. Then it will create the layout of derived, and finally it will create derived’s member functions, which may include creating member functions for base<derived>. So as long as base<derived> doesn’t contain a derived member variable (base classes can never contain a member variable of a type derived from themselves) or a virtual function that requires knowledge of derived’s layout we can indeed do the dicey-looking piece of inheritance above.
This includes being able to call non-virtual public members of derived from base during construction, because it's already part of base. There are strong limitations on this. In particular, if doSomething() depends on anything constructed in derived's constructor it won't work as derived hasn't been constructed yet.
Now, is this actually a good idea? No.
A simple design solution is to use aggregation instead of inheritance.