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.


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 
 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 
 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 ? "
" : "" ); 
24 
25  cout << "Object " << objectID << " destructor runs "
26  << message << endl; 
27 } // end ~CreateAndDestroy destructor 

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.


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 
 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 << "
MAIN 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 << "
MAIN FUNCTION: EXECUTION RESUMES" << endl;
23 CreateAndDestroy fourth( 4, "(local automatic in main)" );
24 cout << "
MAIN FUNCTION: EXECUTION ENDS" << endl;
25 return 0;
26 } // end main
27
28 // function to create objects
29 void create( void )
30 {
31 cout << "
CREATE 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 << "
CREATE 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)
 




C++ How to Program
C++ How to Program (5th Edition)
ISBN: 0131857576
EAN: 2147483647
Year: 2004
Pages: 627
Simiral book on Amazon

Flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net