11.4 Constructors and Destructors in Derived Classes

Instantiating a derived-class object begins a chain of constructor calls in which the derived-class constructor, before performing its own tasks, invokes its direct base class’s constructor either explicitly (via a base-class member initializer) or implicitly (calling the base class’s default constructor). Similarly, if the base class is derived from another class, the base-class constructor is required to invoke the constructor of the next class up in the hierarchy, and so on. The last constructor called in this chain is the one of the class at the base of the hierarchy, whose body actually finishes executing first. The most-derived-class constructor’s body finishes executing last. Each base-class constructor initializes the base-class data members that the derived-class object inherits. In the CommissionEmployee/BasePlusCommissionEmployee hierarchy that we’ve been studying, when a program creates a BasePlusCommissionEmployee object, the CommissionEmployee constructor is called. Since class CommissionEmployee is at the base of the hierarchy, its constructor executes, initializing the private CommissionEmployee data members that are part of the BasePlusCommissionEmployee object. When CommissionEmployee’s constructor completes execution, it returns control to BasePlusCommissionEmployee’s constructor, which initializes the BasePlusCommissionEmployee object’s baseSalary.

Software Engineering Observation 11.6

When a program creates a derived-class object, the derived-class constructor immediately calls the base-class constructor, the base-class constructor’s body executes, then the derived class’s member initializers execute and finally the derived-class constructor’s body executes. This process cascades up the hierarchy if it contains more than two levels.

When a derived-class object is destroyed, the program calls that object’s destructor. This begins a chain (or cascade) of destructor calls in which the derived-class destructor and the destructors of the direct and indirect base classes and the classes’ members execute in reverse of the order in which the constructors executed. When a derived-class object’s destructor is called, the destructor performs its task, then invokes the destructor of the next base class up the hierarchy. This process repeats until the destructor of the final base class at the top of the hierarchy is called. Then the object is removed from memory.

Software Engineering Observation 11.7

Suppose that we create an object of a derived class where both the base class and the derived class contain (via composition) objects of other classes. When an object of that derived class is created, first the constructors for the base class’s member objects execute, then the base-class constructor body executes, then the constructors for the derived class’s member objects execute, then the derived class’s constructor body executes. Destructors for derived-class objects are called in the reverse of the order in which their corresponding constructors are called.

By default, base-class constructors, destructors and overloaded assignment operators (Chapter 10) are not inherited by derived classes. Derived-class constructors, destructors and overloaded assignment operators, however, can call base-class versions.

C++11: Inheriting Base-Class Constructors

Sometimes a derived class’s constructors simply specify the same parameters as the base class’s constructors and simply pass the constructor arguments to the base-class’s constructors. For such cases, C++11 allows you to specify that a derived class should inherit a base class’s constructors. To do so, explicitly include a using declaration of the form


using BaseClass::BaseClass;

anywhere in the derived-class definition. In the preceding declaration, BaseClass is the base class’s name. With a few exceptions (listed below), for each constructor in the base class, the compiler generates a derived-class constructor that calls the corresponding base-class constructor. Each generated constructor has the same name as the derived class. The generated constructors perform only default initialization for the derived class’s additional data members.

When you inherit constructors:

  • Each generated constructor has the same access specifier (public, protected or private) as its corresponding base-class constructor.

  • The default, copy and move constructors are not inherited.

  • If a constructor is deleted in the base class by placing = delete in its prototype, the corresponding constructor in the derived class is also deleted.

  • If the derived class does not explicitly define constructors, the compiler still generates a default constructor in the derived class.

  • A given base-class constructor is not inherited if a constructor that you explicitly define in the derived class has the same parameter list.

  • A base-class constructor’s default arguments are not inherited. Instead, the compiler generates overloaded constructors in the derived class. For example, if the base class declares the constructor


BaseClass(int = 0, double = 0.0);

the compiler generates the following two derived-class constructors without default arguments


DerivedClass();
DerivedClass(int);
DerivedClass(int, double);

These each call the BaseClass constructor that specifies the default arguments.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset