In C++ programming, constructors are foundational elements within a class. They serve the crucial purpose of initializing objects, ensuring they are ready for use.
If you’re new to C++ or looking to deepen your understanding, grasping the concept of constructors is essential.
In this blog post, we’ll delve into the world of constructors in C++, exploring what is constructor in c++, types of constructors, and their significance within the language.
What Is A Constructor In C++?
A C++ class constructor is a special member function of a class responsible for initializing objects of that class. Let’s break down what a constructor in C++ entails:
- 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.
Understanding constructors in C++ is essential for effective object initialization and ensuring proper class functioning. Whether you’re creating basic objects or complex data structures, constructors play a major role in setting up objects for use in your program.
Syntax of Constructors in C++
class ClassName {
public:
ClassName(); // Constructor declaration
};
Syntax for Defining the Constructor Within the Class
class ClassName {
public:
ClassName() { // Constructor definition within the class
// Constructor body
}
};
Syntax for Defining the Constructor Outside the Class
ClassName::ClassName() {
// Constructor definition outside the class
// ClassName:: indicates the scope of the constructor
}
Example of Defining the Constructor Within the Class
#include <iostream>
using namespace std;
class Car {
public:
string brand;
string model;
int year;
Car() { // Constructor defined within the class
brand = "Toyota";
model = "Camry";
year = 2022;
}
};
int main() {
Car myCar;
cout << "Brand: " << myCar.brand << endl;
cout << "Model: " << myCar.model << endl;
cout << "Year: " << myCar.year << endl;
return 0;
}
Output
Brand: Toyota
Model: Camry
Year: 2022
Explaination
- In this example, we have a class Car with member variables brand, model, and year.
- The constructor Car() is defined within the class itself.
- Inside the constructor, default values for brand, model, and year are assigned to “Toyota”, “Camry”, and 2022 respectively.
- When an object myCar of the Car class is created in the main() function, the constructor Car() is automatically called, initializing the object with default values.
- The program then prints out the brand, model, and year of myCar, which are set to “Toyota”, “Camry”, and 2022 respectively.
Real World Example Defining the Constructor Outside the Class
#include <iostream>
using namespace std;
class Car {
public:
string brand;
string model;
int year;
Car(); // Constructor declaration
};
// Constructor definition outside the class
Car::Car() {
brand = "Ford";
model = "Mustang";
year = 2020;
}
int main() {
Car myCar;
cout << "Brand: " << myCar.brand << endl;
cout << "Model: " << myCar.model << endl;
cout << "Year: " << myCar.year << endl;
return 0;
}
Output
Brand: Ford
Model: Mustang
Year: 2020
Explaination
- Here, we declare the constructor Car() within the class Car without defining it.
- Outside the class, we define the constructor Car::Car() which initializes the brand, model, and year member variables of the Car class with the values “Ford”, “Mustang”, and 2020 respectively.
- When myCar object is created in the main() function, the constructor Car::Car() is automatically invoked to initialize it.
- The program then prints out the brand, model, and year of myCar, which are set to “Ford”, “Mustang”, and 2020 respectively.
Learners Tip
Consider using the ‘inline’ keyword when defining constructors outside a class. This technique aligns the external definition with an in-class declaration. However, it’s important to note that ‘inline’ is merely a suggestion to the compiler, not a directive. The compiler may or may not honor it based on various factors.
Get hands-on experience with Top C++ Projects for 2024. Explore more in our blog!
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.
- Memory Management– Constructors implicitly call new and delete operators during memory allocation.
- 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.
Understanding these characteristics helps utilize constructors effectively for initializing objects and managing class behavior in C++ programming.
New to C++?
Dive into ‘Simple C++ Programs‘ for Easy Learning!
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
Let’s understand the Constructor Variants in C++ through real-world examples.
1. 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
};
Example 1: C++ Program to illustrate the concept of default constructors:
#include <iostream>
using namespace std;
class Person {
public:
string name;
int age;
// Default constructor definition
Person() {
name = "John Doe";
age = 30;
}
};
int main() {
Person personObj;
cout << "Name: " << personObj.name << endl;
cout << "Age: " << personObj.age << endl;
return 0;
}
Output
Name: John Doe
Age: 30
Explanation
- In this example, we have a class Person with member variables name and age.
- The default constructor Person() is defined within the class. It initializes the name to “John Doe” and age to 30.
- When an object personObj of the Person class is created in the main() function, the default constructor Person() is automatically called, initializing the object with default values.
- The program then prints out the name and age of personObj, which are set to “John Doe” and 30 respectively.
Example 2: C++ Program to demonstrate the implicit default constructor:
#include <iostream>
using namespace std;
class Book {
public:
string title;
string author;
};
int main() {
Book bookObj;
cout << "Title: " << bookObj.title << endl;
cout << "Author: " << bookObj.author << endl;
return 0;
}
Output
Title:
Author:
Explanation
- In this example, we have a class Book with member variables title and author.
- Since no constructor is defined explicitly, the compiler provides an implicit default constructor.
- When an object bookObj of the Book class is created in the main() function, the default constructor is implicitly called but doesn’t initialize the member variables.
- The program then prints out the uninitialized values of title and author, which are empty strings by default.
Whether you’re just starting or seeking advanced insights, our blog has the perfect Book Recommendations For Mastering C++. Dive in and learn!
2. Parameterized Constructor In C++
A parameterized constructor has parameters that allow the initialization of member variables with specific values passed during object creation.
How To Create A Parameterized Constructor?
To create a parameterized constructor, you define a constructor within the class with parameters corresponding to the values you want to initialize.
Syntax of Parameterized Constructor
class ClassName {
public:
ClassName(Type1 parameter1, Type2 parameter2, ...); // Parameterized constructor declaration
};
Example 1: Defining Parameterized Constructor Inside The Class
#include <iostream>
using namespace std;
class Rectangle {
private:
int length;
int width;
public:
// Parameterized constructor defined inside the class
Rectangle(int l, int w) {
length = l;
width = w;
}
int area() {
return length * width;
}
};
int main() {
Rectangle rect(5, 3); // Creating object with parameters
cout << "Area of Rectangle: " << rect.area() << endl;
return 0;
}
Output
Area of Rectangle: 15
Explanation
- In this example, we have a class Rectangle with member variables length and width.
- The parameterized constructor Rectangle(int l, int w) is defined within the class. It initializes the length and width of member variables with the values passed as parameters.
- When an object rect of the Rectangle class is created in the main() function with parameters 5 and 3, the parameterized constructor is automatically called, initializing the object with specified values.
- The program then calculates and prints the area of the rectangle, which is 15.
Example 2: 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;
}
Output
Area of Rectangle: 24
Explanation
- 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.
Learners Tip
Remember to explicitly include a default constructor without parameters when you add one or more constructors with parameters to a class. If you don’t, the compiler won’t generate one automatically. Although it’s optional, it’s widely advised as a good practice always to supply a default constructor in such scenarios.
Default Arguments With C++ Parameterized Constructor
In C++, parameterized constructors can also utilize default arguments, similar to regular functions. This means that default values can be assigned to parameters in the constructor, following the same rules as for default arguments in functions.
Example 3: Defining Parameterized Constructor with Default Values
#include <iostream>
using namespace std;
class Rectangle {
private:
int length;
int width;
public:
// Parameterized constructor with default values
Rectangle(int l = 0, int w = 0) {
length = l;
width = w;
}
int area() {
return length * width;
}
};
int main() {
Rectangle rect1; // No arguments passed
Rectangle rect2(5); // Only one argument passed
Rectangle rect3(4, 6); // Both arguments passed
cout << "Area of Rectangle 1: " << rect1.area() << endl;
cout << "Area of Rectangle 2: " << rect2.area() << endl;
cout << "Area of Rectangle 3: " << rect3.area() << endl;
return 0;
}
Output
Area of Rectangle 1: 0
Area of Rectangle 2: 0
Area of Rectangle 3: 24
Explanation
- In this example, we have a class Rectangle with member variables length and width.
- The parameterized constructor Rectangle(int l = 0, int w = 0) has default values of 0 for both parameters.
- When objects rect1, rect2 and rect3 of the Rectangle class are created in the main() function; they are initialized using the parameterized constructor.
- rect1 is initialized with default values (0, 0), rect2 with (5, 0), and rect3 with (4, 6).
- The program then calculates and prints the area of each rectangle. Since rect1 and rect2 have one or both sides as 0, their area is 0. rect3 has sides 4 and 6, resulting in an area of 24.
Also, read our blog, “C++ Functions,” for a comprehensive understanding of functions in C++.
3. 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.
Syntax of Copy Constructor
class ClassName {
public:
ClassName(const ClassName& obj); // Copy constructor declaration
};
Example 1: Implicit Copy Constructor
#include <iostream>
using namespace std;
class Person {
public:
string name;
// No explicit copy constructor defined
Person(string n) {
name = n;
}
};
int main() {
Person person1("Alice");
Person person2 = person1; // Copying person1 to person2
cout << "Name of person2: " << person2.name << endl;
return 0;
}
Output
Name of person2: Alice
Explanation
- In this example, we have a class Person with a member variable name.
- The compiler provides an implicit copy constructor since no explicit copy constructor is defined.
- When person1 is copied to person2, the implicit copy constructor is invoked, resulting in person2 being initialized as a copy of person1.
- The program then prints the name of person2, “Alice”, confirming the successful copy.
Example 2: Defining Explicit Copy Constructor
#include <iostream>
using namespace std;
class Person {
public:
string name;
// Explicit copy constructor defined
Person(const Person& obj) {
name = obj.name;
}
Person(string n) {
name = n;
}
};
int main() {
Person person1("Bob");
Person person2 = person1; // Copying person1 to person2
cout << "Name of person2: " << person2.name << endl;
return 0;
}
Output
Name of person2: Bob
Explanation
- In this example, we define an explicit copy constructor for the Person class.
- The explicit copy constructor initializes the new object with the same values as the object passed.
- When person1 is copied to person2, the explicit copy constructor is invoked, copying the name from person1 to person2.
- The program then prints the name of person2, “Bob”, confirming the successful copy.
Example 3: 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;
}
Output
Name of person2: Charlie
Explanation
- This example defines an explicit copy constructor for the Person class.
- We also have a parameterized constructor for the Person class.
- When person1 is copied to person2 using the parameterized constructor, the explicit copy constructor is invoked, copying the name from person1 to person2.
- The program then prints the name of person2, “Charlie”, confirming the successful copy.
- In all examples, the copy constructor plays a crucial role in creating a new object as a copy of an existing object, ensuring data integrity and proper initialization.
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.
Through these functionalities, copy constructors provide a versatile mechanism for managing object duplication, facilitating data integrity, and adapting object attributes to specific requirements.
Learn C++ quickly with our beginner-friendly guide – “C++ Tutorial for Beginners”
4. 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.
Syntax of Move Constructor in C++
class ClassName {
public:
ClassName(ClassName&& obj); // Move constructor declaration
};
Example 1: Demonstrating the Move Constructor
#include <iostream>
#include <vector>
using namespace std;
class Data {
public:
vector<int> data;
// Move constructor definition
Data(Data&& obj) {
data = move(obj.data);
}
};
int main() {
vector<int> vec1 = {1, 2, 3, 4, 5};
Data dataObj1;
dataObj1.data = move(vec1); // Move data from vec1 to dataObj1
cout << "Contents of dataObj1: ";
for (int num : dataObj1.data) {
cout << num << " ";
}
cout << endl;
cout << "Contents of vec1 after move: ";
for (int num : vec1) {
cout << num << " ";
}
cout << endl;
return 0;
}
Output
Contents of dataObj1: 1 2 3 4 5
Contents of vec1 after move:
Explanation:
- In this example, we define a class Data with a member variable data of type vector<int>.
- The move constructor Data(Data&& obj) is defined to facilitate the transfer of ownership of the data vector.
- Within the main() function, we create a vector vec1 with some data and a Data object dataObj1.
- By using a move(vec1), we transfer the contents of vec1 to dataObj1, invoking the move constructor.
- After the move, the data remains intact in dataObj1, while vec1 becomes empty.
- The program then prints the contents of dataObj1 and vec1, demonstrating the successful data transfer.
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.
Syntax of Destructors in C++
class ClassName {
public:
~ClassName(); // Destructor declaration
};
Syntax for Defining the Destructor Within the Class
class ClassName {
public:
~ClassName() {
// Destructor body
}
};
Syntax for Defining the Destructor Outside the Class
ClassName::~ClassName() {
// Destructor definition outside the class
}
Example of Destructors in C++
#include <iostream>
using namespace std;
class Car {
public:
Car() {
cout << "Car object created" << endl;
}
~Car() {
cout << "Car object destroyed" << endl;
}
};
int main() {
Car myCar;
return 0;
}
Output
Car object created
Car object destroyed
Explanation
- 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.
Don’t let the complexity of C++ intimidate you!
Enroll in our Free Introduction to C++ Course and master it step by step.
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.
Wrapping up
This guide has equipped you with a clear understanding of C++ class constructor and its diverse types. You’ve gained crucial insights into initializing objects effectively from default constructors to parameterized, copy, and move constructors.
If you’re eager to explore C++ or software engineering further, explore Great Learning’s free C++ tutorial and advance software engineering courses. Our resources provide:
- Structured learning paths.
- Guiding you from fundamental concepts to advanced topics.
- Empowering you to become proficient in C++ development and beyond.
Whether you’re a beginner looking to grasp the basics or an experienced programmer aiming to refine your skills, Great Learning courses cater to learners of all levels.
By immersing yourself in our comprehensive curriculum, you’ll not only master C++ but also gain a deeper understanding of software engineering principles and best practices, helping you accelerate your career growth.
FAQs
Yes, constructors can be virtual in C++. However, it’s important to note that virtual constructors are not often used directly because constructing an object involves creating a specific type of object, and virtual dispatching only applies after an object has been built. Virtual destructors, on the other hand, are more common and are used to ensure proper cleanup in polymorphic hierarchies.
Yes, constructors can throw exceptions in C++. If an exception is thrown during the construction of an object, the memory for that object is automatically deallocated, and any previously constructed subobjects are destroyed. This ensures that resources are properly managed even in the event of an error during construction.
No, constructors do not have return types, including void. Their purpose is to initialize objects, not to return values. If initialization fails or an exception is thrown during construction, the constructor exits without returning a value.
Constructors are not inherited in derived classes in the same way that other member functions are. However, derived classes can call base class constructors explicitly to initialize the base class subobject of the derived object. If the derived class expressly calls no constructor, the base class’s default constructor is called automatically.