Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What (not) to do in a constructor

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?

like image 595
tyrondis Avatar asked Oct 11 '10 11:10

tyrondis


People also ask

What should not be in a constructor?

A constructor must be called. You can not force the user to use any other function (except the destructor), only by convention.

Is doing a lot in constructors bad?

So yes, doing a lot in constructor is a bad idea in my opinion. Generally I just put some field initializations into the constructor and make an init method to invoke when everybody is on board. I think that your problems may have been caused by violation of SRP and not the constructor doing actual work. – Emily L.

What are the rules for writing the constructor?

Rules to be rememberedA constructor does not have return type. The name of the constructor is same as the name of the class. A constructor cannot be abstract, final, static and Synchronized. You can use the access specifiers public, protected & private with constructors.


1 Answers

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();


An example where polymorphism will work in constructor:
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.

like image 139
Stephane Rolland Avatar answered Oct 04 '22 20:10

Stephane Rolland