Constructors and Destructors
C++
Prepared by
Dr. Swati Joshi
Constructors in C++
What is constructor?
A C++ class constructor is a special member function
of a class responsible for initializing objects of that
class
• Initialization– Constructors initialize objects of a
class during their creation.
• Automatic Invocation– They are automatically
invoked when an object is created.
• Same Name as Class– Constructors have the same
name as the class and do not have a return type.
A constructor is different from normal
functions in following ways:
• Constructor has same name as the class
itself
• Constructors don’t have return type
• A constructor is automatically called
when an object is created.
• If we do not specify a constructor, C++
compiler generates a default constructor.
class ClassName {
public:
ClassName(); // Constructor declaration
};
Defining the Constructor Within the Class
class ClassName {
public:
ClassName() { // Constructor definition within
the class
// Constructor body
}
};
Outside the Class
lassName::ClassName() {
// Constructor definition outside the class
// ClassName:: indicates the scope of the constructor
Example of Defining the Constructor Within the Class
#include <iostream>
• In this example, we have a class Car
using namespace std;
with member variables brand,
class Car { model, and year.
public:
string brand; • The constructor Car() is defined
string model; within the class itself.
int year; • Inside the constructor, default
Car() { // Constructor defined within the class values for brand, model, and year
brand = "Toyota"; are assigned to “Toyota”, “Camry”,
model = "Camry"; and 2022 respectively.
year = 2022;
}
• When an object myCar of the Car
}; class is created in the main()
int main() { function, the constructor Car() is
Car myCar; automatically called, initializing the
cout << "Brand: " << myCar.brand << endl; object with default values.
•
cout << "Model: " << myCar.model << endl; The program then prints out the
brand, model, and year of myCar,
cout << "Year: " << myCar.year << endl;
which are set to “Toyota”, “Camry”,
return 0;
and 2022 respectively.
}
#include <iostream>
using namespace std; • Here, we declare the constructor
Car() within the class Car without
class Car { defining it.
public:
string brand;
• Outside the class, we define the
string model; constructor Car::Car() which
int year; initializes the brand, model, and
year member variables of the
Car(); // Constructor declaration
};
Car class with the values “Ford”,
“Mustang”, and 2020
// Constructor definition outside the class respectively.
Car::Car() {
brand = "Ford"; • When myCar object is created in
model = "Mustang"; the main() function, the
year = 2020;
} constructor Car::Car() is
automatically invoked to
int main() { initialize it.
Car myCar;
• The program then prints out the
cout << "Brand: " << myCar.brand << endl;
brand, model, and year of myCar,
cout << "Model: " << myCar.model << endl;
which are set to “Ford”,
cout << "Year: " << myCar.year << endl;
return 0;
“Mustang”, and 2020
} respectively.
The Attributes Of Constructors In C++
• Declaration Location– Constructors are commonly
declared in the public section of a class, though they can
also be declared in the private section.
• Return Type– Constructors do not return values, thus they
lack a return type.
• Automatic Invocation– Constructors are automatically
invoked upon creating an object of the class.
• Overloading– Constructors can be overloaded, allowing
multiple constructors with different parameter lists.
• Virtual Declaration– Constructors cannot be declared
virtual, which distinguishes them from other member
functions.
• Address Reference– The addresses of constructors cannot
be directly referred to.
• Naming Convention– Constructors are member functions
of a class and share the same name as the class itself.
• Initialization Function– Constructors serve as a particular
type of member function responsible for initializing data
members when objects are created.
• Invocation Timing– Constructors are invoked at the time
of object creation, providing necessary data for the object.
• Automatic Invocation (Reiterated)– Constructors are
automatically called when objects of the class are created.
• Overloading (Reiterated)– Constructors support
overloading, enabling multiple constructors with different
parameter lists.
• Virtual Restriction (Reiterated)– Constructors cannot be
declared virtual, maintaining their distinct behavior within
classes.
Why to use Constructors?
• Object Initialization:
Constructors ensure that an object's data members are initialized with appropriate values
as soon as the object is created. This prevents the use of uninitialized data, which can lead
to unpredictable behavior or errors.
• Enforcing Invariants:
By initializing an object to a valid state, constructors help maintain class invariants, which
are conditions that must always be true for an object of that class.
• Resource Management:
Constructors can be used to acquire resources (like memory, file handles, or network
connections) needed by the object during its lifetime. The corresponding destructors then
release these resources when the object is destroyed.
• Code Organization:
Constructors centralize the initialization logic for a class, making the code more organized
and easier to maintain.
• Overloading for Flexibility:
Constructors can be overloaded, meaning a class can have multiple constructors with
different parameters. This allows for various ways to initialize objects based on the specific
needs of the program.
• Default Initialization:
If no explicit constructor is defined, C++ provides a default constructor that performs
default initialization of member variables. This ensures basic initialization even without a
custom constructor.
Differentiating Constructors In C++
Constructors in C++ can be categorized
according to their usage scenarios. C++
encompasses four distinct types of constructors:
• Default Constructor
• Parameterized Constructor
• Copy Constructor
• Move Constructor
Default Constructor In C++
A default constructor is a constructor that can
be called with no arguments or one that doesn’t
have any parameters. It initializes the member
variables of a class to their default values.
• Syntax of Default Constructor
class ClassName {
public:
ClassName(); // Default constructor declaration
};
#include <iostream>
• In this example, we have a
using namespace std;
class Person with member
variables name and age.
class Person {
public:
• The default constructor
string name; Person() is defined within
int age; the class. It initializes the
name to “swati” and age to
// Default constructor definition 30.
Person() {
name = “swati ";
• When an object personObj
age = 30; of the Person class is created
} in the main() function, the
};
default constructor Person()
is automatically called,
int main() {
initializing the object with
Person personObj;
default values.
cout << "Name: " << personObj.name
<< endl; • The program then prints out
cout << "Age: " << personObj.age << the name and age of
endl; personObj, which are set to
return 0; “swati” and 30 respectively.
}
#include <iostream>
• In this example, we have a
using namespace std; class Book with member
variables title and author.
• Since no constructor is
class Book {
defined explicitly, the
public:
string title;
compiler provides an
string author; implicit default constructor.
}; • When an object bookObj
of the Book class is created
in the main() function, the
int main() { default constructor is
Book bookObj; implicitly called but doesn’t
cout << "Title: " << bookObj.title << initialize the member
endl; variables.
• The program then prints
cout << "Author: " << bookObj.author
out the uninitialized values
<< endl;
of title and author, which
return 0; are empty strings by
} default.
Parameterized Constructor In C++
• A parameterized constructor has parameters
that allow the initialization of member
variables with specific values passed during
object creation.
• To create a parameterized constructor, you
define a constructor within the class with
parameters corresponding to the values you
want to initialize.
ass ClassName {
blic:
ClassName(Type1 parameter1, Type2 parameter2, ...); // Parameterized constructor declar
Defining Parameterized Constructor Inside The Class
#include <iostream> • In this example, we have a class
using namespace std; Rectangle with member variables
length and width.
class Rectangle {
private:
• The parameterized constructor
int length; Rectangle(int l, int w) is defined
int width; within the class. It initializes the
length and width of member
public:
// Parameterized constructor defined inside the class
variables with the values passed as
Rectangle(int l, int w) { parameters.
length = l;
width = w;
• When an object rect of the
} Rectangle class is created in the
main() function with parameters 5
int area() {
and 3, the parameterized
return length * width;
}
constructor is automatically called,
}; initializing the object with specified
values.
int main() {
Rectangle rect(5, 3); // Creating object with parameters • The program then calculates and
cout << "Area of Rectangle: " << rect.area() << endl; prints the area of the rectangle,
return 0; which is 15.
}
Defining Parameterized Constructor Outside the Class
#include <iostream>
using namespace std;
class Rectangle {
private:
int length;
int width;
public:
// Parameterized constructor declaration
Rectangle(int l, int w);
int area() {
return length * width;
}
};
// Parameterized constructor definition outside the class
Rectangle::Rectangle(int l, int w) {
length = l;
width = w;
}
int main() {
Rectangle rect(4, 6); // Creating object with parameters
cout << "Area of Rectangle: " << rect.area() << endl;
return 0;
}
• In this example, we have a class Rectangle with
member variables length and width.
• The parameterized constructor Rectangle(int l, int w) is
declared inside the class but defined outside the class.
• When an object rect of the Rectangle class is created
in the main() function with parameters 4 and 6, the
parameterized constructor is invoked, initializing the
object with specified values.
• The program then calculates and prints the area of the
rectangle, which is 24.
Default Arguments With C++ Parameterized Constructor
#include <iostream>
using namespace std; • In this example, we have a
class Rectangle with member
class Rectangle { variables length and width.
private:
int length;
• The parameterized constructor
int width; Rectangle(int l = 0, int w = 0)
has default values of 0 for both
public: parameters.
// Parameterized constructor with default values
Rectangle(int l = 0, int w = 0) { • When objects rect1, rect2 and
length = l; rect3 of the Rectangle class are
width = w; created in the main() function;
}
they are initialized using the
int area() {
parameterized constructor.
return length * width; • rect1 is initialized with default
} values (0, 0), rect2 with (5, 0),
};
and rect3 with (4, 6).
int main() { • The program then calculates
Rectangle rect1; // No arguments passed and prints the area of each
Rectangle rect2(5); // Only one argument passed
Rectangle rect3(4, 6); // Both arguments passed
rectangle. Since rect1 and rect2
have one or both sides as 0,
cout << "Area of Rectangle 1: " << rect1.area() << endl; their area is 0. rect3 has sides 4
cout << "Area of Rectangle 2: " << rect2.area() << endl; and 6, resulting in an area of
cout << "Area of Rectangle 3: " << rect3.area() << endl; 24.
Copy Constructor In C++
• A copy constructor in C++ is a special member
function that initializes a new object as a copy
of an existing object of the same class.
• It is called when an object is passed by value,
returned by value, or initialized with another
object of the same class.
Implicit Copy Constructor
class ClassName {
public:
ClassName(const ClassName& obj); // Copy constructor
declaration
}
#include <iostream>
• In this example, we have a class
using namespace std;
Person with a member variable
class Person {
name.
public: • The compiler provides an
string name;
implicit copy constructor since
// No explicit copy constructor defined no explicit copy constructor is
defined.
Person(string n) {
name = n; • When person1 is copied to
} person2, the implicit copy
};
constructor is invoked, resulting
nt main() { in person2 being initialized as a
Person person1("Alice"); copy of person1.
Person person2 = person1; // Copying person1 to person2
cout << "Name of person2: " << person2.name << endl;
• The program then prints the
return 0;
name of person2, “Alice”,
Defining Explicit Copy Constructor
#include <iostream>
using namespace std;
class Person { • In this example, we define an
public: explicit copy constructor for the
string name;
Person class.
// Explicit copy constructor defined • The explicit copy constructor
Person(const Person& obj) { initializes the new object with the
name = obj.name; same values as the object passed.
}
• When person1 is copied to
Person(string n) { person2, the explicit copy
name = n; constructor is invoked, copying
}
}; the name from person1 to
person2.
int main() { • The program then prints the
Person person1("Bob"); name of person2, “Bob”,
Person person2 = person1; // Copying person1 to
person2 confirming the successful copy.
cout << "Name of person2: " << person2.name
<< endl;
return 0;
Defining Explicit Copy Constructor with Parameterized Constructor
#include <iostream>
using namespace std;
class Person {
public:
string name;
// Explicit copy constructor with parameterized constructor
Person(const Person& obj) {
name = obj.name;
}
Person(string n) {
name = n;
}
};
int main() {
Person person1("Charlie");
Person person2(person1); // Copying person1 to person2 using parameterized
constructor
cout << "Name of person2: " << person2.name << endl;
return 0;
The Utility Of Copy Constructors
Copy constructors serve several purposes in C++, each
contributing to efficient and accurate object handling.
• Object Replication- Initiates the creation of a new
object by replicating the values from an existing object,
ensuring data consistency.
• Deep Copy Facilitation- Enables the creating deep
copies, particularly useful in scenarios where objects
contain dynamically allocated memory.
• Customized Attribute Modification- Offers the
flexibility to customize attribute modification during
the copying process, allowing specific attributes to be
tailored as necessary.
Move Constructor In C++
• The move constructor, a relatively recent inclusion in the C++
constructor family, offers a distinct approach to object
creation.
• Unlike the copy constructor, which duplicates an object in
new memory, the move constructor leverages move
semantics to transfer ownership of an existing object to a new
one, bypassing redundant copies.
class ClassName {public:
ClassName(ClassName&& obj); // Move constructor declaration
};
clude <iostream>
•
In this example, we define a
clude <vector> class Data with a member
ng namespace std; variable data of type
ass Data { vector<int>.
blic: • The move constructor
ector<int> data; Data(Data&& obj) is defined to
// Move constructor definition facilitate the transfer of
Data(Data&& obj) { ownership of the data vector.
data = move(obj.data); • Within the main() function, we
} create a vector vec1 with some
data and a Data object
main() { dataObj1.
ector<int> vec1 = {1, 2, 3, 4, 5}; • By using a move(vec1), we
Data dataObj1; transfer the contents of vec1 to
dataObj1.data = move(vec1); // Move data from vec1 to dataObj1
dataObj1, invoking the move
cout << "Contents of dataObj1: "; constructor.
or (int num : dataObj1.data) {
• After the move, the data
cout << num << " ";
} remains intact in dataObj1,
out << endl; while vec1 becomes empty.
cout << "Contents of vec1 after move: "; • The program then prints the
or (int num : vec1) { contents of dataObj1 and vec1,
cout << num << " "; demonstrating the successful
} data transfer.
out << endl;
The Benefits Of Move Constructors
Move constructors offer a unique mechanism for managing resources
in C++, providing several advantages:
• Efficient Resource Transfer– Rather than creating copies, move
constructors facilitate the efficient transfer of resource ownership,
optimizing memory usage and enhancing performance.
• Minimized Memory Overhead– By transferring ownership instead
of copying, move constructors prevent unnecessary memory
duplication, reducing memory overhead and improving resource
utilization.
• Custom Resource Handling– Developers have the flexibility to
define custom move constructors tailored to specific resource
transfer scenarios, enabling precise control over resource
management and optimization.
Understanding Destructors In C++
• Destructors are special member functions in C++ that destroy class
objects created by constructors.
Key points to note:
• Destructors have the same name as their class, preceded by a tilde
(~).
• Only one destructor can be defined per class and cannot be
overloaded.
• Destructors are automatically called when objects go out of scope.
• They release memory occupied by objects created by constructors.
• Objects are destroyed in the reverse order of their creation within
the destructor.
• Objects are destroyed in the reverse order of their creation within
the destructor.
• In this example, a class Car is defined
with a constructor and a destructor.
• When the main() function is
executed, an object myCar of the Car
class is created.
• The constructor is automatically
invoked upon creation, printing “Car
object created.”
• When main() finishes executing,
myCar goes out of scope, leading to
the automatic invocation of the
destructor, which prints “Car object
destroyed.”
• This demonstrates the sequence of
object creation and destruction in C+
+ using constructors and destructors.
Key Factors Of Destructors In C++
• Automatic Invocation: The compiler automatically invokes the
destructor when its corresponding object goes out of scope,
releasing memory space no longer needed by the program.
• Argument and Return Value Absence: Destructors do not
require arguments nor return value; hence, they cannot be
overloaded.
• Static and Const Declaration Prohibition: Destructors cannot
be declared static and const, so they must adhere to specific
memory management rules.
• Declaration in Public Section: Destructors should be declared
in the public section of the program, ensuring proper
accessibility and invocation.
• Reverse Order of Invocation: Destructors are called in the
reverse order of their constructor invocation, ensuring orderly
destruction of objects and proper resource deallocation.
• https://www.programiz.com/cpp-programmin
g/online-compiler
/
#include <iostream>
using namespace std;
class MyClass {
public:
// Constructor
MyClass() {
cout << "Constructor called!" << endl;
}
// Destructor
~MyClass() {
cout << "Destructor called!" << endl;
}
};
int main() {
MyClass obj; // Object created, constructor called
cout << "Object is in use." << endl;
return 0; // Object goes out of scope, destructor called
#include <iostream>
using namespace std;
class Student {
private:
string name;
public:
// Parameterized constructor
Student(string n) {
name = n;
cout << "Constructor called for " << name << endl;
}
// Destructor
~Student() {
cout << "Destructor called for " << name << endl;
}
};
int main() {
Student s1("Alice");
Student s2("Bob");
cout << "Students created." << endl;
return 0;
}
#include <iostream>
using namespace std;
// Class with no explicity defined constructors
class A {
public:
};
int main() {
// Creating object
A a;
return 0;
}
#include <iostream>
using namespace std;
class A {
public:
int val;
// Parameterized Constructor
A(int x) {
val = x;
}
};
int main() {
// Creating object with a parameter
A a(10);
cout << a.val;
return 0;
}
#include <iostream>
using namespace std;
class A {
public:
int val;
// Parameterized constructor
A(int x) {
val = x;
}
// Copy constructor
A(A& a) {
val = a.val;
}
};
int main() {
A a1(20);
// Creating another object from a1
A a2(a1);
cout << a2.val;
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
class MyClass {
private:
int b;
public:
// Constructor
MyClass(int &&a) : b(move(a)) {
cout << "Move constructor called!" << endl;
}
void display() {
cout << b <<endl;
}
};
int main() {
int a = 4;
MyClass obj1(move(a)); // Move constructor is called
obj1.display();
return 0;
}