C++ Tutorial

Class and Object

Reference

Inheritance and Derivation

Polymorphism and Virtual Functions

Operator Overloading

Template

Exception

Object Oriented Advanced

Input/Output Stream

File Operations

Destructors for Base And Derived Classes in C++

In C++, destructors play a crucial role in cleaning up resources when objects go out of scope or are explicitly deleted. When dealing with inheritance, understanding how destructors work for both base and derived classes is essential to ensure proper resource management.

In this tutorial, we'll cover destructors for base and derived classes, including the use of virtual destructors.

  • Destructors in Inheritance: When an object of a derived class is destroyed, the destructor of the derived class is called first, followed by the destructor of the base class. This process ensures that resources are released in the reverse order of their acquisition.

Example:

#include <iostream>

class Base {
public:
    Base() {
        std::cout << "Base constructor called." << std::endl;
    }

    ~Base() {
        std::cout << "Base destructor called." << std::endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        std::cout << "Derived constructor called." << std::endl;
    }

    ~Derived() {
        std::cout << "Derived destructor called." << std::endl;
    }
};

int main() {
    Derived obj;
    return 0;
}

Output:

Base constructor called.
Derived constructor called.
Derived destructor called.
Base destructor called.
  • Virtual Destructors: In some cases, you may have a base class pointer pointing to an object of a derived class. When the object is deleted using this pointer, only the base class destructor will be called, potentially leading to resource leaks. To ensure proper cleanup in such scenarios, you should declare the base class destructor as virtual.

Example:

#include <iostream>

class Base {
public:
    Base() {
        std::cout << "Base constructor called." << std::endl;
    }

    virtual ~Base() {
        std::cout << "Base destructor called." << std::endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        std::cout << "Derived constructor called." << std::endl;
    }

    ~Derived() {
        std::cout << "Derived destructor called." << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived();
    delete basePtr;
    return 0;
}

Output:

Base constructor called.
Derived constructor called.
Derived destructor called.
Base destructor called.
  • Importance of Virtual Destructors: Declaring a destructor as virtual in the base class ensures that the correct destructor is called when deleting objects through a base class pointer. If the destructor in the base class is not declared virtual, only the base class destructor will be called, potentially leading to resource leaks.

In summary, when working with base and derived classes in C++, it's important to understand how destructors work in inheritance and the importance of using virtual destructors. This knowledge will help you create more robust and maintainable code, ensuring proper resource cleanup and preventing memory leaks.

  1. C++ destructors in base and derived classes:

    • Description: Demonstrates how to implement destructors in both base and derived classes in C++, emphasizing proper resource cleanup in each class.
    • Example Code:
      class Base {
      public:
          ~Base() {
              // Base class destructor body
          }
      };
      
      class Derived : public Base {
      public:
          ~Derived() {
              // Derived class destructor body
          }
      };
      
  2. Destructors for polymorphic base and derived classes in C++:

    • Description: Introduces polymorphic behavior in destructors and explains the importance of virtual destructors in achieving proper cleanup.
    • Example Code:
      class Base {
      public:
          // Virtual destructor for polymorphism
          virtual ~Base() {
              // Base class destructor body
          }
      };
      
      class Derived : public Base {
      public:
          // Virtual destructor (implicitly virtual due to the virtual destructor in the base class)
          ~Derived() {
              // Derived class destructor body
          }
      };
      
  3. Destructor chaining in C++ with base and derived classes:

    • Description: Demonstrates how destructors in a derived class can invoke the destructor of the base class, achieving proper cleanup in the entire hierarchy.
    • Example Code:
      class Base {
      public:
          ~Base() {
              // Base class destructor body
          }
      };
      
      class Derived : public Base {
      public:
          ~Derived() {
              // Derived class destructor body
              // Destructor chaining to invoke the base class destructor
          }
      };
      
  4. C++ destructor for pure virtual base class and derived class:

    • Description: Illustrates how to implement destructors for a pure virtual base class and its derived class, considering the need for proper cleanup.
    • Example Code:
      class AbstractBase {
      public:
          // Pure virtual destructor
          virtual ~AbstractBase() = 0;
      };
      
      // Destructor definition (pure virtual function requires a definition)
      AbstractBase::~AbstractBase() {
          // Destructor body
      }
      
      class Derived : public AbstractBase {
      public:
          ~Derived() {
              // Derived class destructor body
          }
      };
      
  5. C++ base class destructor and derived class constructor:

    • Description: Discusses the interaction between the destructor of a base class and the constructor of a derived class, emphasizing order of execution.
    • Example Code:
      class Base {
      public:
          ~Base() {
              // Base class destructor body
          }
      };
      
      class Derived : public Base {
      public:
          Derived() {
              // Derived class constructor body
          }
      };
      
  6. Dynamic memory cleanup in base and derived class destructors in C++:

    • Description: Demonstrates how to handle dynamic memory cleanup in both base class and derived class destructors in C++.
    • Example Code:
      class DynamicMemoryBase {
      public:
          int* dynamicData;
      
          // Destructor for dynamic memory cleanup
          ~DynamicMemoryBase() {
              delete dynamicData;
          }
      };
      
      class Derived : public DynamicMemoryBase {
      public:
          ~Derived() {
              // Derived class destructor body
          }
      };