Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A deleted destructor in C++ is a destructor explicitly marked with the = delete specifier, which instructs the compiler to prohibit the destruction of an object of that class. By removing the ability to destroy the object, the compiler enforces strict constraints on object allocation, storage duration, and class hierarchy.

Syntax

class NonDestructible {
public:
    ~NonDestructible() = delete;
};

Technical Implications and Compiler Rules

When a class has a deleted destructor, the C++ compiler alters how the class interacts with memory and scope. 1. Automatic and Static Storage Duration You cannot instantiate objects of the class on the stack (local scope) or globally (static scope). The C++ standard dictates that the compiler must implicitly invoke the destructor when an object with automatic or static storage duration goes out of scope. Because the destructor is deleted, the compiler cannot fulfill this requirement, resulting in a compilation error. 2. Dynamic Storage Duration You can allocate single objects of the class on the heap using the new operator. However, allocating an array of objects dynamically using the new[] operator is ill-formed. The new[] operator requires an accessible, non-deleted destructor because the compiler must be able to destroy already-constructed elements if a subsequent element’s constructor throws an exception. Furthermore, you cannot use the delete expression on any resulting pointer. The delete expression performs two actions: it invokes the destructor, and then it deallocates the memory. Because the destructor is deleted, the delete expression is prohibited. 3. Inheritance A class with a deleted destructor severely restricts inheritance. If a base class has a deleted destructor, the compiler implicitly deletes the derived class’s destructor. Crucially, the derived class’s default constructor is also implicitly deleted, and any user-provided constructors become ill-formed. This occurs because the compiler must be able to invoke the base class destructor to clean up the base subobject if an exception is thrown during the derived class’s construction. Consequently, the derived class cannot be instantiated at all, not even on the heap. 4. Composition If a class contains a member variable of a type that has a deleted destructor, the compiler implicitly deletes the enclosing class’s destructor. Just as with inheritance, the enclosing class’s default constructor is implicitly deleted, and user-provided constructors are ill-formed. This prevents any instantiation of the enclosing class.

Code Visualization

The following block demonstrates the compiler behavior when interacting with a deleted destructor:
class Entity {
public:
    Entity() = default;
    ~Entity() = delete; // Destructor explicitly deleted
};

class DerivedEntity : public Entity {
    // ~DerivedEntity() is implicitly deleted because ~Entity() is deleted
    // DerivedEntity() is implicitly deleted because ~Entity() is deleted
};

struct Container {
    Entity e; 
    // ~Container() is implicitly deleted because member 'e' cannot be destroyed
    // Container() is implicitly deleted because member 'e' cannot be destroyed
};

void memoryMechanics() {
    // 1. STACK ALLOCATION: Compilation Error
    // Entity stackEntity; 
    // Error: attempt to use a deleted function

    // 2. HEAP ALLOCATION (Single): Compiles successfully
    Entity* heapEntity = new Entity();

    // 3. HEAP ALLOCATION (Array): Compilation Error
    // Entity* entityArray = new Entity[5];
    // Error: requires destructor to handle exceptions during array construction

    // 4. DEALLOCATION: Compilation Error
    // delete heapEntity; 
    // Error: attempt to use a deleted function
    
    // 5. DERIVED/COMPOSED INSTANTIATION: Compilation Error
    // DerivedEntity* d = new DerivedEntity();
    // Container* c = new Container();
    // Error: attempt to use a deleted constructor
}

Memory Deallocation Mechanics

Because the standard delete expression is prohibited, memory allocated via new for an object with a deleted destructor cannot be freed through standard object-oriented lifecycle management. To reclaim the memory without invoking the destructor, a developer must bypass object destruction and directly invoke the global deallocation function (e.g., ::operator delete(heapEntity);). This frees the raw memory footprint but skips any resource cleanup normally handled by the destructor.
Master C++ with Deep Grasping Methodology!Learn More