I want to ask you for your best practices regarding constructors in C++. I am not quite sure what I should do in a constructor and what not.
Should I only use it for attribute initializations, calling parent constructors etc.? Or might I even put more complex functions into them like reading and parsing configuration data, setting up external libraries a.s.o.
Or should I write special functions for this? Resp. init()
/ cleanup()
?
What are the PRO's and CON's here?
I figured out yet that for example I can get rid of shared pointers when using init()
and cleanup()
. I can create the objects on the stack as class attributes and initialize it later while it is already constructed.
If I handle it in the constructor I need to instantiate it during runtime. Then I need a pointer.
I really don't know how to decide.
Maybe you can help me out?
The most common mistake to do in a constructor as well as in a destructor, is to use polymorphism. Polymorphism often does not work in constructors !
e.g.:
class A
{
public:
A(){ doA();}
virtual void doA(){};
}
class B : public A
{
public:
virtual void doA(){ doB();};
void doB(){};
}
void testB()
{
B b; // this WON'T call doB();
}
this is because the object B is not yet constructed while performing the constructor of the mother class A... thus impossible for it to call the overriden version of void doA();
class A
{
public:
void callAPolymorphicBehaviour()
{
doOverridenBehaviour();
}
virtual void doOverridenBehaviour()
{
doA();
}
void doA(){}
};
class B : public A
{
public:
B()
{
callAPolymorphicBehaviour();
}
virtual void doOverridenBehaviour()
{
doB()
}
void doB(){}
};
void testB()
{
B b; // this WILL call doB();
}
This time, the reason behind is: at the time the virtual
function doOverridenBehaviour()
is invoked, the object b is already initialized (but not yet constructed), this means that its virtual table is initialized, and thus can perform polymorphism.