[theoretical rambling]
In languages such as Java or those of .Net this is in fact possible, although it doesn't make any sense. The constructor hasn't run yet, so any members are only initialized to their default values.
C++'s approach is much more logical, although it can be a pain in the ass. Perhaps I'd like to see a feature for post-constructors and pre-destructors of some sort... Special structors that are called respectively after the constructor has run and before the destructor is going to be run, with the same fall-through mechanism as the structors themselves have. These special structors should be called by the code that creates or destroys the object of course, just like the normal structors. In this way, you can call foo from Derived1's post-constructor or pre-destructor, so Derived2::foo get's called since it is either after construction (so the object is already a Derived2) or before the destructor (likewise; the object is still a Derived2).
But come to think of it, it can actually be simulated using templates:
#include <stdio.h>
template<class T> class object : public T
{
public:
typedef T super;
object() : super()
{
super::postconstructor();
}
object(const object & other) : super(other)
{
super::postconstructor();
}
template<class P1> object(P1 p1) : super(p1)
{
super::postconstructor();
}
//.
//.
//template<class P1, ..., class PN> object(P1 p1, ..., PN pn) : super(p1, ..., pn)
//{
// obj.postconstructor();
//}
~object()
{
super::predestructor();
}
};
class Base
{
public:
virtual ~Base() { }
virtual void foo() = 0;
};
class Derived1 : public Base
{
public:
Derived1()
{
foo(); // this just calls Derived1::foo
}
~Derived1()
{
foo(); // likewise
}
void foo()
{
printf("1\n");
}
protected:
void postconstructor()
{
foo(); // calls any further derived version of foo()
}
void predestructor()
{
foo(); // likewise
}
};
class Derived2 : public Derived1
{
public:
void foo()
{
printf("2\n");
}
protected:
void postconstructor()
{
Derived1::postconstructor();
// do any more logic here
}
void predestructor()
{
// do any more logic here
Derived1::predestructor();
}
};
int main()
{
Base * x = new object<Derived2>();
delete x;
}
Outputs:
1
2
2
1