Understanding Constructors and Destructors in C++

Markdown

View as Markdown

Constructors and destructors are special member functions in C++ that automate object initialization and cleanup. A constructor is called automatically when an object is created, while a destructor is called automatically when the object is destroyed.

These special functions simplify object management, improve code reliability, and help prevent resource leaks. Constructors can also initialize objects with default or user-defined values, while destructors release resources such as dynamically allocated memory.

Learning Objectives

  • Understand constructors and destructors

  • Create default and parameterized constructors

  • Understand copy constructors

  • Allocate memory using new

  • Release memory using delete

  • Understand when destructors are executed

  • Apply object initialization techniques

What is a Constructor?

A constructor is a special member function that is automatically called when an object is created.

Characteristics:

  • Has the same name as the class

  • Has no return type

  • Executes automatically

  • Initializes object data

General syntax:

class Student

{

public:

    Student()

    {

    }

};

Default Constructor

A default constructor does not accept any parameters.

Example:

#include <iostream>

using namespace std;

class Student

{

public:

    Student()

    {

        cout << "Default Constructor Called";

    }

};

int main()

{

    Student s;

    return 0;

}

Output

Default Constructor Called

Parameterized Constructor

A parameterized constructor accepts values during object creation.

Example:

#include <iostream>

using namespace std;

class Student

{

public:

    string name;

 

    Student(string n)

    {

        name = n;

    }

};

int main()

{

    Student s("John");

    cout << s.name;

    return 0;

}

Output

John

Copy Constructor

A copy constructor creates a new object by copying an existing object.

Example:

#include <iostream>

using namespace std;

class Student

{

public:

    string name;

    Student(string n)

    {

        name = n;

    }

    Student(const Student &obj)

    {

        name = obj.name;

    }

};

int main()

{

    Student s1("John");

    Student s2 = s1;

    cout << s2.name;

    return 0;

}

Output

John

Dynamic Memory Allocation

Objects can be created dynamically using the new operator.

Example:

#include <iostream>

using namespace std;

class Student

{

public:

    void display()

    {

        cout << "Object Created";

    }

};

int main()

{

    Student *s = new Student();

    s->display();

    delete s;

    return 0;

}

Output

Object Created

Destructor

A destructor is automatically called when an object is destroyed.

Characteristics:

  • Same name as the class

  • Prefixed with ~

  • No parameters

  • No return type

Example:

#include <iostream>

using namespace std;

class Student

{

public:

    Student()

    {

        cout << "Constructor Called\n";

    }

    ~Student()

    {

        cout << "Destructor Called";

    }

};

int main()

{

    Student s;

 

    return 0;

}

Output

Constructor Called

Destructor Called

 

Memory Allocation Using new and delete

The new operator allocates memory during runtime.

int *number = new int;

Release allocated memory using:

delete number;

Always pair new with delete to avoid memory leaks.

Advantages of Constructors

  • Automatic object initialization

  • Cleaner code

  • Reduces initialization errors

  • Supports constructor overloading

Advantages of Destructors

  • Automatic resource cleanup

  • Prevents memory leaks

  • Simplifies memory management

  • Releases dynamically allocated resources

Common Mistakes

  • Forgetting to release memory allocated with new

  • Creating unnecessary constructors

  • Writing multiple destructors (only one destructor is allowed per class)

  • Forgetting to use a copy constructor when required

Best Practices

  • Initialize objects using constructors.

  • Release dynamic memory using delete.

  • Keep constructors focused on initialization.

  • Use copy constructors when copying objects.

  • Avoid allocating unnecessary dynamic memory.

Was this article helpful?

Still need help?

Contact us