Destructors - cppreference.com

##### cppreference.com

##### Search

Create account

##### Namespaces

- Page
- Discussion

##### Variants

##### Views

- View
- Edit
- History

##### Actions

# Destructors

From cppreference.com
< cpp‎ | language

A destructor is a special member function that is called when the lifetime of an object ends. The purpose of the destructor is to free the resources that the object may have acquired during its lifetime.

### [edit] Syntax

`~class_name` `();` | (1) |
virtual `~class_name` `();` | (2) |
`~class_name` `() = default;` | (3) | (since C++11)
`~class_name` `() = delete;` | (4) | (since C++11)

1. Typical declaration of a destructor
2. Virtual destructor is usually required in a base class
3. Forcing a destructor to be generated by the compiler
4. Disabling the implicit destructor

| This section is incomplete Reason: syntax details from 12.4/1-3

If no exception-specification is provided, the exception-specification is one that that would be used by the implicitly-declared destructor (see below). In most cases, this is noexcept(true). | (since C++11)

### [edit] Explanation

The destructor is called whenever an object's lifetime ends, which includes

- program termination, for objects with static storage duration
- thread exit, for objects with thread-local storage duration (since C++11)
- end of scope, for objects with automatic storage duration and for temporaries whose life was extended by binding to a reference
- delete-expression, for objects with dynamic storage duration
- end of the full expression, for nameless temporaries
- stack unwinding, for objects with automatic storage duration when an exception escapes their block, uncaught.

The destructor may also be called directly, e.g. to destroy an object that was constructed using placement-new or through an allocator member function such as std::allocator::destroy(), to destroy an object that was constructed through the allocator. Note that calling a destructor directly for an ordinary object, such as a local variable, invokes undefined behavior when the destructor is called again, at the end of scope.

### [edit] Implicitly-declared destructor

If no user-defined destructor is provided for a class type (struct, class, or union), the compiler will always declare a destructor as an `inline public` member of its class.

### [edit] Deleted implicitly-declared destructor

The implicitly-declared or defaulted destructor for class `T` is undefined (until C++11)defined as deleted (since C++11) if any of the following is true:

- `T` has a non-static data member that cannot be destructed (has deleted or inaccessible destructor)
- `T` has direct or virtual base class that cannot be destructed (has deleted or inaccessible destructors)

`T` is a union and has a variant member with non-trivial destructor. | (since C++11)

- The implicitly-declared destructor is virtual (because the base class has a virtual destructor) and the lookup for the deallocation function (operator delete() results in a call to ambiguous, deleted, or inaccessible function.

### [edit] Trivial destructor

The destructor for class `T` is trivial if all of the following is true:

- The destructor is not user-provided (meaning, it is implicitly-defined or defaulted)
- The destructor is not virtual (that is, the base class destructor is not virtual)
- All direct base classes have trivial destructors
- All non-static data members of class type (or array of class type) have trivial destructors

A trivial destructor is a destructor that performs no action. Objects with trivial destructors don't require a delete-expression and may be disposed of by simply deallocating their storage. All data types compatible with the C language (POD types) are trivially destructible.

### [edit] Implicitly-defined destructor

If the implicitly-declared destructor is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. This implicitly-defined destructor has an empty body.

As with any implicitly-defined special member function, the exception specification of the implicitly-defined destructor is noexcept(true) unless it must call a user-defined destructor for a member or a base subobject with a different exception specification. | (since C++11)

### [edit] Destruction sequence

For both user-defined or implicitly-defined destructors, after the body of the destructor is executed, the compiler calls the destructors for all non-static non-variant members of the class, in reverse order of declaration, then it calls the destructors of all direct base classes in reverse order of construction (which in turn call the destructors of their members and their base classes, etc), and then, if this object is of most-derived class, it calls the destructors of all virtual bases.

Even when the destructor is called directly (e.g. obj.~Foo();), the return statement in ~Foo() does not return control to the caller immediately: it calls all those member and base destructors first.

### [edit] Virtual destructors

Deleting an object through pointer to base invokes undefined behavior unless the destructor in the base class is virtual:

    class Base {
     public:
        virtual ~Base() {}
    };
    class Derived : public Base {};
    Base* b = new Derived;
    delete b; // safe

A common guideline is that a destructor for a base class must be either public and virtual or protected and nonvirtual

### [edit] Pure virtual destructors

A destructor may be declared pure virtual, for example in a base class which needs to be made abstract, but has no other suitable functions that could be declared pure virtual. Such destructor must have a definition, since all base class destructors are always called when the derived class is destroyed:

    class AbstractBase {
     public:
        virtual ~AbstractBase() = 0;
    };
    AbstractBase::~AbstractBase() {}
    class Derived : public AbstractBase {};
    // AbstractBase obj;   // compiler error
    Derived obj;           // OK

### [edit] Exceptions

As any other function, a destructor may terminate by throwing an exception (this usually requires it to be explicitly declared noexcept(false)) (since C++11), however if this destructor happens to be called during stack unwinding, std::terminate is called instead.

Although std::uncaught_exception may sometimes be used to detect stack unwinding in progress, it is generally considered bad practice to allow any destructor to terminate by throwing an exception. One example where this functionality is used is the library SOCI, which relies on the ability of the destructors of certain nameless temporaries to throw exceptions.

### [edit] Example

Run this code

    #include <iostream>

    struct A
    {
        int i;

        A ( int i ) : i ( i ) {}

        ~A()
        {
            std::cout << "~a" << i << std::endl;
        }
    };

    int main()
    {
        A a1(1);
        A* p;

        { // nested scope
            A a2(2);
            p = new A(3);
        } // a2 out of scope

        delete p; // calls the destructor of a3
    }

Output:

    ~a2
    ~a3
    ~a1

Retrieved from "http://en.cppreference.com/mwiki/index.php?title=cpp/language/destructor&oldid=71634"
Category:

- Todo with reason