In standard C++, we know that a virtual method call in a base class constructor will not invoke the derived class override. This is an area where C++/CLI behaves differently from standard C++. The vtables are initialized even before the base class constructor is called. There was a post in the MSDN forums earlier today where someone asked a question related to this and I thought I’d blog about it. Take a look at the following code snippet :
ref class ManA
{
protected:
NatA* _natA;
virtual void Init()
{
_natA = new NatA();
}
public:
ManA()
{
Init();
}
};
ref class ManB : ManA
{
NatB* GetNatB()
{
return static_cast<NatB*>(_natA);
}
protected:
virtual void Init() override
{
_natA = new NatB();
}
public:
ManB()
{
}
};
}
Now, if you do a gcnew ManB() you’ll see that ManB::Init is called first (this is done during the base class ctor) and then ManB‘s constructor is called. Of course this means that you should not access any member in ManB that needs to be created or initialized in the constructor. In fact this is probably not a good practice at all – but the poster asking this question had a special requirement and this was one straightforward way to address his problem. Note that C# users won’t find this particularly odd because this is just the way C# behaves too. This behavior is dictated by the fact that the CLR works with vtables directly, and both C# and C++/CLI just followed the curriculum.