21.5 Constructors and Destructors in Derived Classes

I l @ ve RuBoard

Constructors and destructors behave differently from normal member functions, especially when used with derived classes. When a derived-class variable is created, the constructor for the base class is called first, followed by the constructor for the derived class.

Example 21-4 defines a simple base class and uses it to create a derived class.

Example 21-4. cons/class.cpp
 #include <iostream> class base_class {     public:         base_class(  ) {             std::cout << "base_class constructor called\n";         }         ~base_class(  ) {             std::cout << "base_class destructor called\n";         } }; class derived_class:public base_class {     public:         derived_class(  ) {             std::cout << "derived_class constructor called\n";         }         ~derived_class(  ) {             std::cout << "derived_class destructor called\n";         } }; 

Now when we execute the code:

 derived_class *sample_ptr = new derived_class; 

the program prints:

 base_class constructor called derived_class constructor called 

After the variable is destroyed , the destructors are called. The destructor for the derived class is called first, followed by the destructor for the base class. So when we destroy the variable with the statement:

 delete sample_ptr; sample_ptr = NULL; 

we get:

 derived_class destructor called base_class destructor called 

But C++ has a surprise lurking for us. Remember that derived-class objects can operate as base-class objects. For example:

 base_class *base_ptr = new derived_class; 

is perfectly legal. However, there is a problem when the variable is deleted:

 delete base_ptr; base_ptr = NULL; 

You see, base_ptr is a pointer to a base class. At this point, all the code can see is the base class. There is no way for C++ to know that there is a derived class out there. So when the variable is deleted, C++ fails to call the derived class destructor.

The output of the delete statement is:

 base_class destructor called 

We have just tricked C++ into deleting a class without calling the proper destructor.

We need some way to tell C++, "Hey, there is a derived class out there and you might want to call its destructor." The way we do this is to make the destructor for the base class a virtual function:

 class base_class {     public:         base_class(  ) {            std::cout << "base_class constructor called\n";         }         virtual ~base_class(  ) {            std::cout << "base_class destructor called\n";         } }; 

The keyword virtual normally means, "Call the function in the derived class instead of the one in the base class." For the destructor, it has a slightly different meaning. When C++ sees a virtual destructor, it will call the destructor of the derived class and then call the destructor of the base class.

So with the virtual destructor in place, we can safely delete the base_class variable, and the program will output the proper information:

 derived_class destructor called base_class destructor called 

Question 21-1: Why does Example 21-1 fail when we delete the variable list_ptr? The program seems to get upset when it tries to call clear at line 21.

Example 21-5. blow/blow.cpp
 #include <iostream> #include <cstdlib> class list {     private:         int item;       // Current item number     public:         virtual void clear(  ) = 0;         void next_item(  ) {             ++item;         }         list(  ) {              item = 0;         }         virtual ~list(  ) {            clear(  );         } }; class list_of_integers : public list {     public:         int array[100];   // Place to store the items         void clear(  ) {             int i;      // Array index             for (i = 0; i < 100; ++i)                  array[i] = 0;         } }; int main(  ) {     list_of_integers *list_ptr = new list_of_integers;     // Cause problems     delete list_ptr;     list_ptr = NULL;     return (0); } 
I l @ ve RuBoard


Practical C++ Programming
Practical C Programming, 3rd Edition
ISBN: 1565923065
EAN: 2147483647
Year: 2003
Pages: 364

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