www.gibmonks.com

Main Page

Previous Page
Next Page

[Page 500 (continued)]

9.8. When Constructors and Destructors Are Called

Constructors and destructors are called implicitly by the compiler. The order in which these function calls occur depends on the order in which execution enters and leaves the scopes where the objects are instantiated. Generally, destructor calls are made in the reverse order of the corresponding constructor calls, but as we will see in Figs. 9.119.13, the storage classes of objects can alter the order in which destructors are called.

Constructors are called for objects defined in global scope before any other function (including main) in that file begins execution (although the order of execution of global object constructors between files is not guaranteed). The corresponding destructors are called when main terminates. Function exit forces a program to terminate immediately and does not execute the destructors of automatic objects. The function often is used to terminate a program when an error is detected in the input or if a file to be processed by the program cannot be opened. Function abort performs similarly to function exit but forces the program to terminate immediately, without allowing the destructors of any objects to be called. Function abort is usually used to indicate an abnormal termination of the program. (See Chapter 24, Other Topics, for more information on functions exit and abort.)

The constructor for an automatic local object is called when execution reaches the point where that object is definedthe corresponding destructor is called when execution leaves the object's scope (i.e., the block in which that object is defined has finished executing). Constructors and destructors for automatic objects are called each time execution enters and leaves the scope of the object. Destructors are not called for automatic objects if the program terminates with a call to function exit or function abort.

The constructor for a static local object is called only once, when execution first reaches the point where the object is definedthe corresponding destructor is called when main terminates or the program calls function exit. Global and static objects are destroyed in the reverse order of their creation. Destructors are not called for static objects if the program terminates with a call to function abort.

The program of Figs. 9.119.13 demonstrates the order in which constructors and destructors are called for objects of class CreateAndDestroy (Fig. 9.11 and Fig. 9.12) of various storage classes in several scopes. Each object of class CreateAndDestroy contains (lines 1617) an integer (objectID) and a string (message) that are used in the program's output to identify the object. This mechanical example is purely for pedagogic purposes. For this reason, line 23 of the destructor in Fig. 9.12 determines whether the object being destroyed has an objectID value 1 or 6 and, if so, outputs a newline character. This line helps make the program's output easier to follow.


[Page 501]

Figure 9.11. CreateAndDestroy class definition.

 1  // Fig. 9.11: CreateAndDestroy.h
 2  // Definition of class CreateAndDestroy.
 3  // Member functions defined in CreateAndDestroy.cpp.
 4  #include <string>
 5  using std::string;
 6
 7  #ifndef CREATE_H
 8  #define CREATE_H
 9
10  class CreateAndDestroy
11  {
12  public:
13     CreateAndDestroy( int, string ); // constructor
14     ~CreateAndDestroy(); // destructor             
15  private:
16     int objectID; // ID number for object
17     string message; // message describing object
18  }; // end class CreateAndDestroy
19
20  #endif

Figure 9.12. CreateAndDestroy class member-function definitions.

 1  // Fig. 9.12: CreateAndDestroy.cpp
 2  // Member-function definitions for class CreateAndDestroy.
 3  #include <iostream>
 4  using std::cout;
 5  using std::endl;
 6
 7  #include "CreateAndDestroy.h"// include CreateAndDestroy class definition
 8
 9  // constructor                                                    
10  CreateAndDestroy::CreateAndDestroy( int ID, string messageString )
11  {                                                                 
12     objectID = ID; // set object's ID number                       
13     message = messageString; // set object's descriptive message   
14                                                                    
15     cout << "Object " << objectID << "   constructor runs   "      
16        << message << endl;                                         
17  } // end CreateAndDestroy constructor                             
18
19  // destructor                                               
20  CreateAndDestroy::~CreateAndDestroy()                       
21  {                                                           
22     // output newline for certain objects; helps readability 
23     cout << ( objectID == 1 || objectID == 6 ? "\n" : "" );  
24                                                              
25     cout << "Object " << objectID << "   destructor runs    "
26        << message << endl;                                   
27  } // end ~CreateAndDestroy destructor                       


[Page 502]

Figure 9.13 defines object first (line 12) in global scope. Its constructor is actually called before any statements in main execute and its destructor is called at program termination after the destructors for all other objects have run.

Function main (lines 1426) declares three objects. Objects second (line 17) and fourth (line 23) are local automatic objects, and object third (line 18) is a static local object. The constructor for each of these objects is called when execution reaches the point where that object is declared. The destructors for objects fourth and then second are called (i.e., the reverse of the order in which their constructors were called) when execution reaches the end of main. Because object third is static, it exists until program termination. The destructor for object third is called before the destructor for global object first, but after all other objects are destroyed.

Function create (lines 2936) declares three objectsfifth (line 32) and seventh (line 34) as local automatic objects, and sixth (line 33) as a static local object. The destructors for objects seventh and then fifth are called (i.e., the reverse of the order in which their constructors were called) when create terminates. Because sixth is static, it exists until program termination. The destructor for sixth is called before the destructors for third and first, but after all other objects are destroyed.


[Page 503]
Figure 9.13. Order in which constructors and destructors are called.
(This item is displayed on pages 502 - 503 in the print version)

 1  // Fig. 9.13: fig09_13.cpp
 2  // Demonstrating the order in which constructors and
 3  // destructors are called.
 4  #include <iostream>
 5  using std::cout;
 6  using std::endl;
 7
 8  #include "CreateAndDestroy.h" // include CreateAndDestroy class definition
 9
10  void create( void ); // prototype
11
12  CreateAndDestroy first( 1, "(global before main)" ); // global object
13
14  int main()
15  {
16     cout << "\nMAIN FUNCTION: EXECUTION BEGINS" << endl;
17     CreateAndDestroy second( 2, "(local automatic in main)" );   
18     static CreateAndDestroy third( 3, "(local static in main)" );
19
20     create(); // call function to create objects
21
22     cout << "\nMAIN FUNCTION: EXECUTION RESUMES" << endl;
23     CreateAndDestroy fourth( 4, "(local automatic in main)" );
24     cout << "\nMAIN FUNCTION: EXECUTION ENDS" << endl;
25     return 0;
26  } // end main
27
28  // function to create objects
29  void create( void )
30  {
31     cout << "\nCREATE FUNCTION: EXECUTION BEGINS" << endl;
32     CreateAndDestroy fifth( 5, "(local automatic in create)" );    
33     static CreateAndDestroy sixth( 6, "(local static in create)" );
34     CreateAndDestroy seventh( 7, "(local automatic in create)" );  
35     cout << "\nCREATE FUNCTION: EXECUTION ENDS" << endl;
36  } // end function create

 Object 1   constructor runs (global before main)

 MAIN FUNCTION: EXECUTION BEGINS
 Object 2   constructor runs (local automatic in main)
 Object 3   constructor runs (local static in main)

 CREATE FUNCTION: EXECUTION BEGINS
 Object 5   constructor runs (local automatic in create)
 Object 6   constructor runs (local static in create)
 Object 7   constructor runs (local automatic in create)

 CREATE FUNCTION: EXECUTION ENDS
 Object 7   destructor runs (local automatic in create)
 Object 5   destructor runs (local automatic in create)

 MAIN FUNCTION: EXECUTION RESUMES
 Object 4   constructor runs (local automatic in main)

 MAIN FUNCTION: EXECUTION ENDS
 Object 4   destructor runs (local automatic in main)
 Object 2   destructor runs (local automatic in main)

 Object 6   destructor runs (local static in create)
 Object 3   destructor runs (local static in main)

 Object 1   destructor runs (global before main)



Previous Page
Next Page