Suppose I have two C++ classes:
class A
{
public:
A() { fn(); }
virtual void fn() { _n = 1; }
int getn() { return _n; }
protected:
int _n;
};
clas
Other answers have already explained why virtual
function calls don't work as expected when called from a constructor. I'd like to instead propose another possible work around for getting polymorphic-like behavior from a base type's constructor.
By adding a template constructor to the base type such that the template argument is always deduced to be the derived type it's possible to be aware of the derived type's concrete type. From there, you can call static
member functions for that derived type.
This solution does not allow non-static
member functions to be called. While execution is in the base type's constructor, the derived type's constructor hasn't even had time to go through it's member initialization list. The derived type portion of the instance being created hasn't begun being initialized it. And since non-static
member functions almost certainly interact with data members it would be unusual to want to call the derived type's non-static
member functions from the base type's constructor.
Here is a sample implementation :
#include
#include
struct Base {
protected:
template
explicit Base(const T*) : class_name(T::Name())
{
std::cout << class_name << " created\n";
}
public:
Base() : class_name(Name())
{
std::cout << class_name << " created\n";
}
virtual ~Base() {
std::cout << class_name << " destroyed\n";
}
static std::string Name() {
return "Base";
}
private:
std::string class_name;
};
struct Derived : public Base
{
Derived() : Base(this) {} // `this` is used to allow Base::Base to deduce T
static std::string Name() {
return "Derived";
}
};
int main(int argc, const char *argv[]) {
Derived{}; // Create and destroy a Derived
Base{}; // Create and destroy a Base
return 0;
}
This example should print
Derived created
Derived destroyed
Base created
Base destroyed
When a Derived
is constructed, the Base
constructor's behavior depends on the actual dynamic type of the object being constructed.