When are constructors and destructors called?
It may be useful to understand when a basic constructor, a copy
constructor, an intializing constructor or a destructor is called.
Suppose we have a class called Box which has a basic constructor,
an initializing constructor, a copy constructor and destructor.
Here are some general guidelines:
- The basic constructor is called when an instance of Box
is created and is not initialized.
- The initializing constructor is called when an instance of Box
is created and is initialized.
- The copy constructor is called whenever it is necessary to make a
copy of an instance of Box. This happens more often than many
people realize.
- The destructor is called when an instance of Box is destroyed.
This will happen when a variable passes out of its scope or
when we use the delete or delete [] operators.
Here is an example:
Box F(Box, Box &); // Line 1
int main() // Line 2
{ // Line 3
Box A; // Line 4
Box B; // Line 5
Box * C; // Line 6
Box * D; // Line 7
A = SomeValue; // Line 8
B = A; // Line 9
C = new Box(SomeValue); // Line 10
D = new Box(A); // Line 11
// various code, irrelevant // Line 12
D = C; // Line 13
// irrelevant code // Line 14
if (true) // Line 15
{ // Line 16
Box E; // Line 17
E = SomeOtherValue; // Line 18
B = F(*C, A); // Line 19
// more irrelevant code // Line 20
delete D; // Line 21
} // Line 22
return 0; // Line 23
} // Line 24
Box F(Box Arg1, Box & Arg2) // Line 25
{ // Line 26
Box T = Arg2; // Line 27
// lots of irrelevant code // Line 28
return T; // Line 29
} // Line 30
Let's go through this a line at a time.
- Line 1 is a prototype statement.
- Line 4 creates a Box instance A, so the basic constructor is called.
- Line 5 creates a Box instance, so the basic constructor is called.
- Line 6 creates a pointer to a Box, not an instance of Box.
- Line 7 creates a pointer to a Box, not an instance of Box.
- Line 8 calls the assignment operator.
- Line 9 calls the assignment operator.
- Line 10 creates a new Box instance *C dynamically and initializes it,
so the initializing constructor is called.
- Line 11 creates a new Box instance *D dynamically as a copy of
another instance A, so the copy constructor is called.
- At line 13, we set D = C without deleting the old *D, so
we have just created a memory leak.
- Line 17 creates a Box instance E, so the basic constructor is called.
- Line 18 calls the assignment operator.
- Line 19 calls the function F and then the assignment operator.
We have also just created a memory leak by changing the value of
B without first deleting *B. Also see line 25 below.
- Line 21 deletes the instance *D of Box, so the destructor will be
called. As we had D = C, the pointer C now contains the address
of something which has been deleted--this can be a headache.
- At line 22, the variable E, an instance of Box, passes out of
scope, so the destructor is called.
- At line 23, the program returns 0, which is a copy of 0, so the
copy constructor for int is called (at least in principle).
- At line 24, the variable A, an instance of Box, passes out of
scope, so the destructor is called.
- At line 25, the function F is called and the actual arguments
are matched with the formal arguments. As Arg1 is not a reference
argument, the copy constructor will be called to make a copy of
the actual argument. As Arg2 is a reference argument, no copy
needs to be made.
- Line 27 creates a new instance T of Box as a copy of Arg2. Although
it looks as if it uses the basic constructor and the assignment
operator, in fact the copy constructor will be called.
- Line 29 returns an (unnamed) instance of Box which will be a copy of T,
so the copy constructor is called.
- At line 30, the variable T, an instance of Box, passes out of
scope, and the destructor is called. The same thing happens for
Arg1.
The above list is not guaranteed to be complete. For instance, when is
the temporary value returned by F going to be destroyed? Is it destroyed
after line 19, after line 22 or after line 24?
Likewise, the program ends without deleting all the instances of Box
which were created dynamically. These presumably disappear after line
24 when cleanup work is done.