I am aware that it is unsafe to call a virtual method from within the constructor of the class in which the method is declared virtual (or pure virtual).
However, I am wondering if the following is safe:
class Base
{
public:
void helper()
{
this->foo();
}
protected:
virtual void foo() = 0;
};
class Derived : public Base
{
public:
Derived()
{
this->helper();
}
protected:
void foo() override
{
//...
}
};
Yes, the virtual method foo() is called from within a constructor, but it is called from within the constructor for the class which implements foo().
Here is a working example: https://godbolt.org/z/nz4YsbqYT
But, is this well-defined by the standard for all compilers?
Yes, in the example you've given, it is.
Yes.
*thisis aDerivedin the constructor ofDerived, soDerived::foowill be called fromhelper.Safe? Well... If you expect everyone to know how it works, it is. Someone may however do:
... and, without other additions, expect this version of
footo be called when instantiating anEvenMoreDerived. That will of course not happen since the call tohelperis done in theDerivedconstructor, so it'll still beDerived::foothat's being called, notEvenMoreDerived::foo.One possible way to avoid mistakes like that if you want to call
virtualmethods in the constructor is to make the classfinal:... or make
foofinal: