Sessions on advanced C++ programming
Half-day seminar at CCC
Author: Zoltán Porkoláb
Budapest, 2007
A.3. Constructors and destructors
Topics
- Role of contructor
In object-oriented languages constructors have the role to
initialize newly created objects. Different styles are used
including factory methods. Structures/classes without
constructors can be instantiated without constructor call. If
at least one constructor is defined for a class, objects must be
created through one of the constructors.
- Constructor as conversion operator
Constructors have a secondary role in C++: in can be used as
conversion operator from their parametes(s) to the class type.
This feature is frequently used the save coding effort. Sometime
however this automatic conversion is dangerous: we can use the
explicit keyword to forbid constructors as conversions.
- Creation and destruction time
Objects in C++ could be created in many different ways: there are
named automatic, free store, nonstatic member, array element,
local static, global and temporary objects. The time
of creation and destruction vary of this differend type of objects.
- Creation of subobjects
Base class objects and data members are called subobjects.
Subobjects are created during the initialisation process of the
object, in order of inheritance declaration and attribute declaration.
The initialization list of constructor is the place to
provide parameters for subobjects. If initialization list contradicts
the declaration order than it will be rearranged: the declaration list
is the relevant.
- Creation of statics
The global static, namespace and static member
objects are created at the beginning of the program, and destroyed
at its end. In practice we can take their constructor running time
at the very beginning of the main function, and - in normal
execution - the running time of destructor is the end of main. On
abnormal termination however the destructors are not guaranteed to run.
The local static variables are allocated on global store,
but their construction are delayed until the controll first reaches
the declaration.
- Arrays
Array elements are created when the array object itself starts to
live. The elements are constructed from the lower indices to the
upper one. There might be problem if the element class has no
default constructor, since no way to pass constructor parameters
to array elemenst. However the copy constructor can be used to
initialized the array. Be care: arrays are not polymorphic!.
- Temporaries
Temporary objects are created in part of expressions. Their life
expands until the evolution of the full expression. Most
cases there is no problem with temporaries, but there might be
extreme cases, where special care is needed.
- "Virtual" constructor and destructor
Polymorphic classes most cases require virtual destructor.
However there is no virtual constructor, we can simulate it with
clone function.
- Objects with special storage
We can restrict the existence of objects regarding their
storage class. The solution is tricky, but sometime
can be usefull the create classes with such restrictions.
- Optimizing (copy) constructor
The "normal" way to create copy constructor and operation=
is to immediatelly copy the objects. In real life implementation
this would be very inefficient: too many copy operations needed.
We can optimize the operations using different startegies. One of
the most widely used startegy is the reference counting,
which delays copy operations until it is neccessary.