Constructors in C++ are special member functions that are automatically called when an object of a class is created. They initialize the object's data members and allow setting up initial values when creating an instance.
Key Characteristics of Constructors
- Same name as the class: Constructors have the same name as the class they belong to.
- No return type: Constructors do not have a return type, not even void.
- Called automatically: Constructors are called automatically when an object is created.
- Overloading: Constructors can be overloaded, allowing multiple ways to initialize an object.
Types of Constructors
- Default Constructor: A constructor with no parameters.
- Parameterized Constructor: A constructor with parameters, allowing specific initial values.
- Copy Constructor: A constructor that creates a copy of an existing object.
- Constructor with Default Arguments: A constructor with default values for parameters.
Let’s go through each type with examples.
1. Default Constructor
A default constructor is a constructor with no parameters. It initializes objects with default values.
#include <iostream> using namespace std; class Car { public: string make; string model; int year; // Default Constructor Car() { make = "Unknown"; model = "Unknown"; year = 0; cout << "Default constructor called!" << endl; } void displayInfo() { cout << "Make: " << make << ", Model: " << model << ", Year: " << year << endl; } }; int main() { Car car1; // Default constructor is called car1.displayInfo(); return 0; }
Explanation:
- The default constructor Car() sets make, model, and year to default values.
- When Car car1; is executed, the default constructor initializes car1.
Output:
Default constructor called! Make: Unknown, Model: Unknown, Year: 0
2. Parameterized Constructor
A parameterized constructor accepts parameters to initialize the object with specific values.
#include <iostream> using namespace std; class Car { public: string make; string model; int year; // Parameterized Constructor Car(string m, string mo, int y) { make = m; model = mo; year = y; cout << "Parameterized constructor called!" << endl; } void displayInfo() { cout << "Make: " << make << ", Model: " << model << ", Year: " << year << endl; } }; int main() { Car car1("Toyota", "Camry", 2020); // Parameterized constructor is called car1.displayInfo(); return 0; }
Explanation:
- Car(string m, string mo, int y) is a parameterized constructor that initializes make, model, and year.
- When Car car1(“Toyota”, “Camry”, 2020); is called, the parameterized constructor sets the specified values.
Output:
Parameterized constructor called! Make: Toyota, Model: Camry, Year: 2020
3. Copy Constructor
A copy constructor creates a new object as a copy of an existing object. The default copy constructor performs a shallow copy, but you can define your own copy constructor.
#include <iostream> using namespace std; class Car { public: string make; string model; int year; // Parameterized Constructor Car(string m, string mo, int y) { make = m; model = mo; year = y; cout << "Parameterized constructor called!" << endl; } // Copy Constructor Car(const Car &c) { make = c.make; model = c.model; year = c.year; cout << "Copy constructor called!" << endl; } void displayInfo() { cout << "Make: " << make << ", Model: " << model << ", Year: " << year << endl; } }; int main() { Car car1("Toyota", "Corolla", 2021); // Parameterized constructor is called Car car2 = car1; // Copy constructor is called car2.displayInfo(); return 0; }
Explanation:
- Car(const Car &c) is a copy constructor that creates a copy of car1 in car2.
- When Car car2 = car1; is executed, the copy constructor initializes car2 with car1's data.
Output:
Parameterized constructor called! Copy constructor called! Make: Toyota, Model: Corolla, Year: 2021
4. Constructor with Default Arguments
A constructor with default arguments allows optional parameters. If an argument isn’t provided, the default value is used.
#include <iostream> using namespace std; class Rectangle { private: int length; int width; public: // Constructor with default arguments Rectangle(int l = 5, int w = 10) { length = l; width = w; } int area() { return length * width; } }; int main() { Rectangle rect1; // Uses default arguments Rectangle rect2(8, 12); // Uses provided arguments cout << "Area of rect1: " << rect1.area() << endl; cout << "Area of rect2: " << rect2.area() << endl; return 0; }
Explanation:
- Rectangle(int l = 5, int w = 10) allows you to create a rectangle with default dimensions if no arguments are passed.
- Rectangle rect1; uses default values, while Rectangle rect2(8, 12); uses specified values.
Output:
Area of rect1: 50 Area of rect2: 96
5. Overloaded Constructors
C++ allows overloading constructors by defining multiple constructors with different parameter lists, enabling different ways to initialize an object.
#include <iostream> using namespace std; class Box { private: int length; int width; int height; public: // Default constructor Box() { length = 1; width = 1; height = 1; } // Parameterized constructor for custom dimensions Box(int l, int w, int h) { length = l; width = w; height = h; } int volume() { return length * width * height; } }; int main() { Box box1; // Calls default constructor Box box2(3, 4, 5); // Calls parameterized constructor cout << "Volume of box1: " << box1.volume() << endl; cout << "Volume of box2: " << box2.volume() << endl; return 0; }
Explanation:
- Box() and Box(int l, int w, int h) are overloaded constructors.
- Box box1; calls the default constructor, while Box box2(3, 4, 5); calls the parameterized constructor.
Output:
Volume of box1: 1 Volume of box2: 60
6. Member Initialization List in Constructors
Member initialization lists allow initializing members directly and are especially useful for const and reference members.
#include <iostream> using namespace std; class Person { private: const string name; int age; public: // Constructor with member initialization list Person(string n, int a) : name(n), age(a) {} void display() { cout << "Name: " << name << ", Age: " << age << endl; } }; int main() { Person person("Alice", 30); person.display(); return 0; }
Explanation:
- Person(string n, int a) : name(n), age(a) initializes name and age directly.
- Member initialization is necessary for const members like name.
Output:
Name: Alice, Age: 30
7. Dynamic Memory Allocation in Constructors
Constructors can allocate dynamic memory using pointers, but you should also provide a destructor to free the memory.
#include <iostream> using namespace std; class Array { private: int *data; int size; public: // Constructor with dynamic memory allocation Array(int s) { size = s; data = new int[size]; for (int i = 0; i < size; i++) { data[i] = i + 1; } } // Destructor to free allocated memory ~Array() { delete[] data; } void display() { for (int i = 0; i < size; i++) { cout << data[i] << " "; } cout << endl; } }; int main() { Array arr(5); arr.display(); return 0; }
Explanation:
- The constructor Array(int s) allocates dynamic memory using new.
- The destructor ~Array() releases the allocated memory with delete[].
Output:
1 2 3 4 5
8. Constructor Delegation
In C++11 and later, constructors can call each other
, a feature known as constructor delegation.
#include <iostream> using namespace std; class Rectangle { private: int length; int width; public: // Default constructor Rectangle() : Rectangle(1, 1) {} // Calls the parameterized constructor // Parameterized constructor Rectangle(int l, int w) : length(l), width(w) {} int area() { return length * width; } }; int main() { Rectangle rect1; // Calls default constructor Rectangle rect2(4, 5); // Calls parameterized constructor cout << "Area of rect1: " << rect1.area() << endl; cout << "Area of rect2: " << rect2.area() << endl; return 0; }
Explanation:
- Rectangle() delegates to Rectangle(int l, int w) with default dimensions.
- rect1 uses delegated values, while rect2 uses specific values.
Output:
Area of rect1: 1 Area of rect2: 20
Summary Table of Constructor Types
Constructor Type | Description | Example |
---|---|---|
Default Constructor | Initializes object with default values | ClassName() |
Parameterized Constructor | Initializes object with specified values | ClassName(int x) |
Copy Constructor | Creates a new object as a copy of an existing object | ClassName(const ClassName &obj) |
Constructor with Default Arguments | Constructor with parameters having default values | ClassName(int x = 10) |
Overloaded Constructors | Multiple constructors with different parameter lists | ClassName(), ClassName(int x) |
Member Initialization List | Initializes members directly (useful for const and references) | ClassName(int x) : member(x) {} |
Dynamic Memory Allocation | Allocates memory with new in the constructor | ClassName() { ptr = new int[n]; } |
Constructor Delegation | One constructor calls another within the same class | ClassName() : ClassName(10) {} |
Complete Example with Multiple Constructors
This example combines multiple constructor types, including default, parameterized, and copy constructors.
#include <iostream> using namespace std; class Box { private: int length; int width; public: // Default constructor Box() : length(1), width(1) { cout << "Default constructor called." << endl; } // Parameterized constructor Box(int l, int w) : length(l), width(w) { cout << "Parameterized constructor called." << endl; } // Copy constructor Box(const Box &b) : length(b.length), width(b.width) { cout << "Copy constructor called." << endl; } int area() const { return length * width; } }; int main() { Box box1; // Default constructor Box box2(5, 10); // Parameterized constructor Box box3 = box2; // Copy constructor cout << "Area of box1: " << box1.area() << endl; cout << "Area of box2: " << box2.area() << endl; cout << "Area of box3: " << box3.area() << endl; return 0; }
Sample Output:
Default constructor called. Parameterized constructor called. Copy constructor called. Area of box1: 1 Area of box2: 50 Area of box3: 50
Constructors in C++ are essential for object initialization and enable flexibility through overloading and copy construction.