Constructors and Destructors in C++
An in-depth look at constructors and destructors in C++ — the different constructor types, why destructors matter for resource management, and how they tie into the RAII pattern.

Every object in C++ has a birth and a death — a moment it's created, and a moment its memory is reclaimed. Constructors and destructors are how you hook into both of those moments, and getting them right is central to writing C++ that doesn't leak resources.
What Is a Constructor?
A constructor is a special member function that runs automatically when an object is created. It shares the class's name, has no return type, and its job is to set the object up in a valid initial state.
cppclass Rectangle { public: int width, height; Rectangle() { // default constructor width = 0; height = 0; } };
The Types of Constructors
Default Constructor
Takes no arguments. If you don't write any constructor at all, C++ generates one automatically — but it disappears the moment you define any other constructor yourself.
Parameterized Constructor
Takes arguments so you can initialize an object with specific values at creation time.
cppclass Rectangle { public: int width, height; Rectangle(int w, int h) : width(w), height(h) {} }; Rectangle r(5, 10); // width = 5, height = 10, set immediately
Copy Constructor
Creates a new object as a copy of an existing one. C++ generates a default copy constructor that copies each member, which is fine for simple data — but dangerous when a class manages a resource like dynamically allocated memory, since a shallow copy would leave two objects pointing at the same memory.
cppRectangle r1(5, 10); Rectangle r2 = r1; // copy constructor runs
Move Constructor (Modern C++)
Transfers ownership of a resource from a temporary object instead of copying it, which avoids unnecessary duplication — central to how modern C++ handles performance-sensitive resource transfers.
What Is a Destructor?
A destructor is a special member function that runs automatically when an object goes out of scope or is explicitly deleted. It's named with a ~ before the class name, takes no arguments, and returns nothing.
cppclass FileHandler { public: FileHandler() { std::cout << "File opened\n"; } ~FileHandler() { std::cout << "File closed\n"; } }; void process() { FileHandler f; } // f goes out of scope here — destructor runs automatically, prints "File closed"
Why Destructors Actually Matter: RAII
This automatic cleanup is the foundation of a core C++ pattern called RAII — Resource Acquisition Is Initialization. The idea: tie a resource's lifetime (memory, a file handle, a network connection, a lock) directly to an object's lifetime. Acquire the resource in the constructor, release it in the destructor. As long as the object is properly scoped, the resource is guaranteed to be cleaned up — even if an exception is thrown partway through a function.
cppclass Connection { public: Connection() { /* open connection */ } ~Connection() { /* close connection automatically */ } }; void doWork() { Connection conn; // opened // ... work happens, even if an exception is thrown here ... } // conn's destructor still runs, connection is still closed
This is exactly what modern smart pointers (unique_ptr, shared_ptr) are built on — they're RAII wrappers around raw memory.
Constructor and Destructor Order
When objects are composed of other objects, or when inheritance is involved, order matters: constructors run base class first, then derived class; destructors run in the exact reverse order — derived class first, then base class. This ensures a derived object is never left partially destroyed while its base class parts still exist.
The Takeaway
Constructors guarantee an object starts life in a valid state; destructors guarantee it cleans up after itself when that life ends. Together, they're the mechanism behind RAII — arguably C++'s single most important pattern for writing code that manages resources safely without manual bookkeeping at every call site.

