Base* ptr = new Derived();
delete ptr;
NON-VIRTUAL DESTRUCTOR:
Calls Base::~Base() ONLY ──► Derived members & memory leaked! (UB)
VIRTUAL DESTRUCTOR:
Calls Derived::~Derived() ──► Calls Base::~Base() ──► 100% Clean!Virtual Destructors in C++: Safe Cleanup Through Base-Class Pointers
Direct Answer & Core Concept
Detailed Explanation & Mechanics
1. Memory Leak Mechanics (Non-Virtual Destructor Bug):
2. Standard Guideline:
A base class destructor should be either public virtual (for polymorphic deletion) or protected non-virtual (if polymorphism is not used for deletion).
Runnable Code Example: Virtual Destructors in C++
C++20 / C++23#include <iostream>
#include <memory>
class SafeBase {
public:
SafeBase() { std::cout << "SafeBase allocated.\n"; }
// Virtual destructor guarantees full derived destruction
virtual ~SafeBase() { std::cout << "SafeBase destroyed.\n"; }
};
class HeavyDerived : public SafeBase {
private:
int* largeBuffer;
public:
HeavyDerived() : largeBuffer(new int[1000]) {
std::cout << "HeavyDerived allocated 4000 bytes on heap.\n";
}
~HeavyDerived() override {
delete[] largeBuffer;
std::cout << "HeavyDerived freed heap memory safely.\n";
}
};
int main() {
std::cout << "--- Polymorphic Deletion via Base Pointer ---\n";
SafeBase* polyPtr = new HeavyDerived();
delete polyPtr; // Triggers HeavyDerived dtor first, then SafeBase dtor
std::cout << "--- Deletion Complete ---\n";
return 0;
}