blog
blog copied to clipboard
C++ Destructors
Reference: Book: Starting Out with C++ from Control Structures to Objects, byTony Gaddis, ninth edition
Concept: A destructor is a member function that is automatically called when an object is destroyed.
Destructors are member functions with the same name as the class, precede by a tilde character (~
). For example, the destructor for the Rectangle
class would be named ~Rectangle
.
Destructors are automatically called when an object is destroyed. In the same way that constructors set things up when an object is created, destructors perform shutdown procedures when the object goes out of existence. For example, a common use of destructor is to free memory that was dynamically allocated by the class object.
Example01:
// This program demonstrates a destructor.
#include <iostream>
using namespace std;
class Demo {
public:
Demo(); // Constructor
~Demo(); // Destructor
};
Demo::Demo() {
cout << "Welcome to the constructor!\n";
}
Demo::~Demo() {
cout << "The destructor is now running.\n";
}
int main() {
// Define a Demo object.
Demo demoObject;
return 0;
}
Output:
Welcome to the constructor!
The destructor is now running.
Example02:
A more realistic example of a class with a destructor.
The ContactInfo
class holds the following data about a contact:
- The contact's name
- The contact's phone number
The constructor accepts arguments for both items. The name
and phone number
are passed as a pointer to a C-string
.
Rather than storing the name
and phone number
in a char array with a fixed size, the constructor gets the length of the C-string
and dynamically allocates just enough memory to hold it.
The destructor frees the allocated memory when the object is destroyed.
#include <iostream>
#include <cstring> // Needed for strlen and strcpy
using namespace std;
// ContactInfo class declaration.
class ContactInfo {
private:
char *name; // The name
char *phone; // The phone number
public:
// Constructor
ContactInfo(char *n, char *p) {
// Allocate just enough memory for the name and phone number.
name = new char[strlen(n) + 1];
phone = new char[strlen(p) + 1];
// Copy the name and phone number to the allocated memory.
strcpy(name, n);
strcpy(phone, p);
}
// Destructor
~ContactInfo() {
delete [] name;
delete [] phone;
}
// The return type of the `getName` and `getPhoneNumber` functions is const char *.
// This means each function returns a pointer to a constant char.
// This is a security measure. It prevents any code that calls the functions
// from changing the string that the pointer points to.
const char *getName() const {
return name;
}
const char *getPhoneNumber() const {
return phone;
}
};
int main() {
// Define a ContactInfo object.
ContactInfo entry("Kristen Lee", "555-2021");
// Display the object's data.
cout << "Name: " << entry.getName() << endl;
cout << "Phone Number: " << entry.getPhoneNumber() << endl;
return 0;
}
Output:
Name: Kristen Lee
Phone Number: 555-2021
In addition to the fact that destructors are automatically called when an objects is destroyed, the following points should be mentioned:
- Like constructors, destructors have no return type,
- Destructors cannot accept arguments, so they never have a parameter list.
Destructors and Dynamically Allocated Class Objects
If a class object has been dynamically allocated by the new
operator, its memory should be released when the object is no longer needed.
For example, in the following code objectPtr
is a pointer to a dynamically allocated ContactInfo
class object:
// Define a ContactInfo pointer.
ContactInfo *objectPtr = nullptr;
// Dynamically create a ContactInfo object.
objectPtr = new ContactInfo("Kristen Lee", "555-2021");
The following statement shows the delete
operator being used to destroy the dynamically created object:
delete objectPtr;
When the object pointed to by objectPtr
is destroyed, its destructor is automatically called.