display | more...

As outlined in the Constructor node, in C++ a default constructor is merely one which requires no arguments. A constructor which provides default arguments for all of its parameters would be classed as a default constructor. Therefore, these two constructors are default constructors because you can create an object of their class type without providing arguments:

class something
    // try this...
    something () : value(0) {}
    // or, alternatively...
    something (int v = 0) : value(v) {}

    int value;

As any C++ book will tell you, if you do not define any constructors yourself the compiler will synthesise one for you.

Or will it?

Consider what a constructor actually does - class designers mainly use it for data member initialisation, something which isn't actually required by the language for its built-in types and which, therefore, the compiler doesn't really care all that much about. Bear in mind that when a class object is created its data members are instantiated before its constructor is called, and take a look at this class:

class something_else
    int another_value;

Fairly useless, you may conclude, and you'd probably be right. However, when an object of type something_else is created, an uninitialised int called another_value will be created in memory, leaving nothing for a constructor to do. In this case, the class is said to have an implicit, trivial default constructor which, in practice, will not be synthesised.

When is an implicit non-trivial default constructor synthesised? If a class has other class types as data members then their constructors need to be called, so the containing class will be provided with a default constructor by the compiler purely to invoke the default constructors of its member class objects. This would also apply to an inherited class, which must invoke the constructor(s) of its base(s).

Another situation where the compiler is required to synthesise a constructor is if the class declares or inherits one or more virtual member functions. The compiler inserts a pointer to the virtual method table into the class; therefore when an object of its type is created, the pointer will obviously need to be initialised with the table's address - enter the default constructor. This is also the case with classes which inherit from a virtual base class. The location of the base class must be made available at runtime to all class objects which derive from it, and therefore a pointer is once again inserted and initialised via a default constructor.

In summary then, a default constructor is provided by the compiler only in the above four situations, when the class contains data members which the implementation needs to initialise, not when it only contains members the programme needs initialised, which is of course the responsibility of the programmer. Whatever happens at compile time, synthesised default constructors will never initialise built-in types, arrays of them, pointers to them, etc., for you.


Log in or register to write something here or to contact authors.