C++ Destructors

A C++ destructor is a special class method that runs automatically when an object is destroyed. Destructors are commonly used for cleanup work, such as releasing memory, closing files, or printing a final message.

A destructor is the opposite partner of a constructor: the constructor sets up a new object, and the destructor cleans up when that object’s lifetime ends.

Destructor Syntax

A destructor has the same name as the class, but it starts with a tilde character, ~. Like a constructor, it has no return type. Unlike many constructors, a destructor cannot take parameters.

  • The destructor name is ~ClassName.
  • It has no return type, not even void.
  • It takes no parameters.
  • Each class can have only one destructor.
  • C++ calls it automatically when an object is destroyed.

Example: Destructor Runs At The End Of Scope

This program creates a small class named Timer. Its constructor prints a message when an object is created, and its destructor prints a message when that object is destroyed.

#include <iostream>
#include <string>

class Timer {
public:
    std::string name;

    Timer(std::string timerName) {
        name = timerName;
        std::cout << "Starting " << name << std::endl;
    }

    ~Timer() {
        std::cout << "Stopping " << name << std::endl;
    }
};

int main(void) {
    std::cout << "Program begins" << std::endl;

    {
        Timer shortTask("short task");
        std::cout << "Inside the block" << std::endl;
    }

    std::cout << "Program ends" << std::endl;

    return 0;
}

Output:

Program begins
Starting short task
Inside the block
Stopping short task
Program ends

How The Example Works

The line Timer shortTask("short task"); creates an object inside a nested block. When the object is created, C++ automatically calls the constructor Timer(std::string timerName), so the program prints Starting short task.

The object shortTask exists only until the closing brace of that nested block. When execution leaves the block, the object’s lifetime ends. C++ then automatically calls ~Timer(), so the program prints Stopping short task before continuing with the rest of main.

When Destructors Run

For ordinary local objects, a destructor runs when the program leaves the scope where the object was created. This can happen at the end of a function, at the end of a block, or when returning from a function.

If several local objects in the same scope are destroyed, they are usually destroyed in the reverse order from how they were created. This helps objects clean up in a predictable way.

Why Destructors Matter

Many beginner classes do not need to write a destructor. If a class only stores values like int, double, or std::string, C++ already knows how to clean those members up automatically.

Destructors become important when a class owns a resource that must be released. For example, a class might allocate memory with new, open a file, or lock something that must later be unlocked. Putting cleanup code in the destructor makes the cleanup happen even if the programmer forgets to call a separate cleanup method.

Common Mistakes

  • Writing a return type, such as void ~Timer(). Destructors do not have return types.
  • Adding parameters, such as ~Timer(int value). Destructors take no parameters.
  • Trying to call the destructor directly in normal code. In most beginner programs, let C++ call it automatically.
  • Assuming every class needs a custom destructor. If the class does not own a manual resource, the automatic destructor is often enough.

Takeaway: a destructor runs automatically when an object is destroyed, giving a class one reliable place to clean up its resources.