Classes Constructor
the constructor is used to construct the object of a class. It is a special member function that outlines the steps that are performed when an instance of a class is created in the program.
A constructor’s name must be exactly the same as the name of its class and it does not have a return type, writing
void
as return type is a good practice but it is not mandatory.
Default Constructor
it is a constructor that either takes no arguments or has default values for all its parameters.
class Example {
public:
Example() { // Default constructor
// Initialization code
}
};
The default constructor does not need to be explicitly defined. Even if we don’t create it, the C++ compiler will call a default constructor and set data members to some junk values.
Parameterized Constructor
it is a constructor that takes one or more parameters.
class Example {
public:
Example(int x, int y) { // Parameterized constructor
// Initialization code
}
};
Copy Constructor
It is a constructor that takes a reference to an object of the same class as a parameter, used to create a new object as a copy of an existing object.
class Example {
public:
Example(const Example &obj) { // Copy constructor
// Copy initialization code
}
};
Move Constructor
It is a constructor that takes an rvalue reference to an object of the same class as a parameter, used to transfer ownership of resources from a temporary object to a new object which improving the performance.
class Example {
public:
Example(Example &&obj) { // Move constructor
// Move initialization code
}
};
Constructor Delegation
it is a mechanism where one constructor calls another constructor of the same class, used to avoid code duplication by reusing code from another constructor.
class Example {
public:
Example(int x) : Example(x, 0) { // Constructor delegation
// Additional initialization code
}
Example(int x, int y) {
// Initialization code
}
};
Explicit Constructor
It is a constructor that is marked with the explicit
keyword to prevent implicit conversions, and used to prevent the compiler from using the constructor for implicit type conversions, making the code safer.
class Example {
public:
explicit Example(int x) {
// Initialization code
}
};
this
Pointer
The this
pointer points to the calling object itself. We can use this
pointer to access a data member of the calling object.
Since
this
is a pointer, we use the->
operator to access members instead of.
.
class Date {
int day;
int month;
int year;
public:
// Default constructor
Date(){
// We must define the default values for day, month, and year
day = 0;
month = 0;
year = 0;
}
// Parameterized constructor
Date(int day, int month, int year){
// Using this pointer
this->day = day;
this->month = month;
this->year = year;
}
// A simple print function
void printDate(){
cout << "Date: " << day << "/" << month << "/" << year << endl;
}
};
Examples
To use the different types of constructors
// Default constructor
Example exmaple;
// Parameterized constructor
Example example1(1,2);
// Copy constructor
Example example2 = example1;
// Moce constructor
Example example3 = std::move(example1);
// Constructor delegation
Example example4(1);
// Exceplicit constructor
// this will work with implicit constructor, and it will not work with explicit
Example example5 = 1;
// only this will work
Example example6(1,2);
Destructor
Every class with a constructor should also have a destructor to properly clean up resources. The destructor is called when an object goes out of scope or is deleted.
class Example {
public:
~Example() { // Destructor
// Cleanup code
}
};
Default and Delete
Normally the compiler will generate the constructor and the destructor automatically if it is not defined by the user, but you can control this behaviour by using default
and delete
keywords.
- The
default
keyword is used when you want the compiler to generate a default implementation of a constructor (or other special member functions like the copy constructor, move constructor, copy assignment operator, or move assignment operator).
#include
class Example {
public:
int x;
// Default constructor using 'default'
Example() = default;
// Parameterized constructor
Example(int value) : x(value) {}
// Default copy constructor using 'default'
Example(const Example&) = default;
};
int main() {
// Calls the default constructor
Example e1;
// Calls the parameterized constructor
Example e2(10);
// Calls the default copy constructor
Example e3 = e2;
std::cout << "e1.x = " << e1.x << "\n"; // Undefined value (not initialized)
std::cout << "e2.x = " << e2.x << "\n"; // Output: e2.x = 10
std::cout << "e3.x = " << e3.x << "\n"; // Output: e3.x = 10
return 0;
}
- The
delete
keyword is used when you want to prevent the compiler from generating a default implementation of a constructor (or other special member functions). It essentially disables the use of that function, preventing objects from being created or copied in a certain way.
#include
class Example {
public:
int x;
// Default constructor
Example() : x(0) {}
// Parameterized constructor
Example(int value) : x(value) {}
// Delete the copy constructor
Example(const Example&) = delete;
// Delete the assignment operator
Example& operator=(const Example&) = delete;
};
int main() {
// Calls the default constructor
Example e1;
// Calls the parameterized constructor
Example e2(10);
// Error: Copy constructor is deleted
// Example e3 = e2;
// Error: Assignment operator is deleted
// e1 = e2;
std::cout << "e1.x = " << e1.x << "\n"; // Output: e1.x = 0
std::cout << "e2.x = " << e2.x << "\n"; // Output: e2.x = 10
return 0;
}
The behavior of the compiler varies based on what special members the user has defined. We can find details in the diagram by Howard Hinnant below:
Default Constructor |
Destructor | Copy Constructor |
Copy Assignment |
Move Constructor |
Move Assignment |
|
---|---|---|---|---|---|---|
User Declares Nothing | default | default | default | default | default | default |
Any Constructor | Not declared | default | default | default | default | default |
Default Constructor |
User declared |
default | default | default | default | default |
Destructor | default | User declared | default | default | Not declared | Not declared |
Copy Constructor |
Not declared | default | User declared |
default | Not declared | Not declared |
Copy Assignment |
default | default | default | User declared | Not declared | Not declared |
Move Constructor |
Not declared | default | deleted | deleted | User declared | Not declared |
Move Assignment |
default | default | deleted | deleted | Not declared | User declared |