Virtual method calls from constructors

C++ and C# varies considerably in how virtual method calls from constructors work. I feel that the approach taken by C++ is significantly better. Let's consider the following code in C++.

 #include <iostream>
using namespace std;
class Base
{
public:
    Base()
    {
        Foo();
    }
    virtual void Foo()
    {
        cout << "Base::Foo" << endl;
    }
};

class Derived : Base
{
public:
    Derived()
    {
    }
    void  Foo()
    {
        cout << "Derived::Foo" << endl;
    }
};
Derived* der = new Derived(); 

The output of the program is Base::Foo.

Here the Base class constructor is calling the virtual method Foo. In C++  (as with most OO language) the Base class is created before the Derived class and hence the base class constructor is called first. So when the call to Foo is made in Base::Base(), Derived is not yet created and hence the call Foo() ends in Base::Foo and not its override in Derived::Foo.

In C# the behavior is different and always the most derived override is called.

 class Base
{
    public Base()
    {
        Foo();
    }

    public virtual void Foo()
    {
        Console.WriteLine("Base::Foo");
    }
}

class Derived : Base
{
    string str = null;
    public Derived()
    {
        str = "Hello world";
    }

    public override void  Foo()
    {
        Console.WriteLine("Derived::Foo");
        //Console.WriteLine(str);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Derived der = new Derived(); 
    }
}

In this case the output is Derived::Foo. Even in C# the base class is created first and its constructor is called first. However calls to virtual methods always land on the most derived version which in this case is Derived::Foo().

However there are issues with this. Even though Derived::Foo gets called, Derived class is still not initialized properly and its constructor is not yet called. In the above code the variable str is not initialized and if it is referred from Derived::Foo a null reference will occur. So I tend to believe that even though C++ implementation needs a bit more understanding of object creation (vtable build-up) it is safer.

Due to all these subtleties its always recommended to not refer to virtual methods from ctors. If for example you are writing some code that will be used by others (as in Frameworks) then this may break the client developers if they derive from your class. They may never anticipate that calls to their overrides may hit un-initialized variables which they have explicitly initialized in the derived class's constructor.