Types of Constructors in C++
C++ Types of Constructors
In this article, we will learn more about different types of constructors in C++. A constructor is a special type of member function that is automatically called when the object of the class is created. The name of the constructor is the same as the name of the class and it does not have any return type.
Types of Constructors in C++
- Default Constructor
- Parameterized Constructor
- Copy Constructor
- Shallow Copy
- Deep Copy
Difference between constructor and member function
- Constructor name must be the same as class name but functions cannot have the same name as the class name.
- Constructors do not have a return type whereas functions must have a return type.
- Constructors are automatically called when an object is created.
- A member function can be virtual, but there is no concept of virtual constructors.
- Constructors are invoked at the time of object creation automatically and cannot be called explicitly using class objects.
1. Default Constructor in C++
- The default constructor is the constructor which doesn’t take any argument. It has no parameters.
- In this case, as soon as the object is created the constructor is called which initializes its data members.
- A default constructor is so important for the initialization of object members, that even if we do not define a constructor explicitly, the compiler will provide a default constructor implicitly
Sample Code
#include <iostream> using namespace std; class construct { public: int a, b; // Default Constructor construct() { a = 10; b = 20; } }; int main() { construct c; int sum = c.a + c.b; cout << "a : " << c.a << endl; cout << "b : " << c.b << endl; cout << "sum : " << sum << endl; return 0; }
Output
a : 10 b : 20 sum : 30
2. Parameterized Constructor in C++
- Arguments can be passed to the parameterised constructors.
- These arguments help initialize an object when it is created.
- To create a parameterized constructor, simply add parameters to it the way you would to any other function.
- When you define the constructor’s body, use the parameters to initialize the object.
We can also have more than one constructor in a class and that concept is called constructor overloading.
Uses of Parameterized constructor:
- It is used to initialize the various data elements of different objects with different values when they are created.
- It is used to overload constructors.
Sample Code
#include <iostream> using namespace std; class PrepInsta { private: int a, b; public: PrepInsta(int a1, int b1) { a = a1; b = b1; } int getA() { return a; } int getB() { return b; } }; int main() { PrepInsta obj1(10, 15); cout << "a = " << obj1.getA() << ", b = " << obj1.getB(); return 0; }
Output
a = 10, b = 15
3. Copy Constructor in C++
- A copy constructor is a member function which initializes an object using another object of the same class.
- Whenever we define one or more non-default constructors( with parameters ) for a class, a default constructor( without parameters ) should also be explicitly defined as the compiler will not provide a default constructor in this case.
- An object can be initialized with another object of same type. This is same as copying the contents of a class to another class.
- For a better understanding of Copy Constructor in C++ (click here).
What is a Copy Constructor?
class_name (class-name &){
....
}
- Copy Constructor is a type of constructor which is used to create a copy of an already existing object of a class type.
- It is usually of the form X (X&), where X is the class name.
- The compiler provides a default Copy Constructor to all the classes.
Code
#include <iostream> using namespace std; class PrepInsta { private: int x, y; public: PrepInsta() { // empty default constuctor } PrepInsta(int x1, int y1) { x = x1; y = y1; cout << "Parameterized constructor called here" << endl; } // User defined Copy constructor PrepInsta(const PrepInsta &p2) { x = p2.x; y = p2.y; cout << "Copy constructor called here" << endl; } int getX() { return x; } int getY() { return y; } }; int main() { // Trying to call parameterized constructor here PrepInsta p1(10, 15); // Trying to call copy constructor here PrepInsta p2 = p1; // Trying to call Copy constructor here (Another way of doing so) PrepInsta p3(p1); PrepInsta p4; // Here there is no copy constructor called only assignment operator happens p4 = p1; cout << "\nFor p4 no copy constructor called only assignment operation happens\n" << endl; // displaying values for both constructors cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY(); cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY(); cout << "\np3.x = " << p3.getX() << ", p3.y = " << p3.getY(); cout << "\np4.x = " << p4.getX() << ", p4.y = " << p4.getY(); return 0; }
Output
Parameterized constructor called here Copy constructor called here Copy constructor called here For p4 no copy constructor called only assignment operation happens p1.x = 10, p1.y = 15 p2.x = 10, p2.y = 15 p3.x = 10, p3.y = 15 p4.x = 10, p4.y = 15
PrepInsta p2 = p1;
PrepInsta p3(p1);
However, PrepInsta p4; followed by p4 = p1; doesn’t call copy constructor, its just simply and assignment operator
Types of Copy Constructors
It is really great way of creating new object initialisations and is still widely used by programmers.
There are two types of copy constructors which are –
- Default Copy Constructors (Does Shallow Copying)
- User Defined Copy Constructors (Does Deep Copying)
We will learn more about these two in detail below –
Shallow Copy
When we do not create our own copy constructor. C++ compiler will create a default copy constructor for each class which does a member-wise copy between objects.
This default copy constructor does shallow copy.
Code
Let us see an example to see how this works –#include <iostream> #include <string.h> using namespace std; class PrepInsta { char *prepString; public: // Note : No user defined Copy constuctor created here PrepInsta(const char *prepString1) { //We are invoiking Dynamic memory allocation here prepString = new char[16]; strcpy(prepString, prepString1); } /* concatenate method */ void concatenate(const char *prepString1) { // using function to Concatenating two strings strcat(prepString, prepString1); } void print() { cout << prepString << endl; } }; /* main function */ int main() { PrepInsta obj1("Prep"); //Copy constructor PrepInsta obj2 = obj1; cout << "Before concatenation - " << endl; obj1.print(); obj2.print(); // obj1 is invoking concatenate() // but change will also be reflected in obj2 (shallow copy) // see more explanation in below comments obj1.concatenate("Insta"); cout << "\nAfter concatenation - " << endl; // as we didn't create any user defined copy constructor // compiler created default copy constuctor in backend on its own // So both obj1 & obj2 variables share same memory (shallow copy) // any change in obj1 also reflects in obj2 obj1.print(); obj2.print(); return 0; }
Output
Before concatenation - Prep Prep After concatenation - PrepInsta PrepInstaAny change in obj1 also reflects in obj2 (shallow copy)
Deep Copy
When we create our own user-defined copy constructor. The individual copies of memory are created for each object and thus there is no sharing of memory.
This user-defined copy constructor does Deep copy.
Code
#include <iostream> #include<string.h> using namespace std; class PrepInsta { char *prepString; public: PrepInsta (const char *str) { //We are invoking Dynamic memory allocation here prepString = new char[16]; strcpy(prepString, str); } // here we are doing the change of adding additional code // for user defined copy constructor (Deep Copy) PrepInsta (const PrepInsta &x2) { //We are invoking Dynamic memory allocation here prepString = new char[16]; strcpy(prepString, x2.prepString); } void concatenate(const char *prepString1) { // using function to Concatenating two strings strcat(prepString, prepString1); } ~PrepInsta() { delete [] prepString; } void print() { cout << prepString << endl; } }; /* main function */ int main() { PrepInsta p1("Prep"); PrepInsta p2 = p1; //copy constructor cout << "Before concatenation - " << endl; p1.print(); p2.print(); p1.concatenate("Insta"); cout << "\nAfter concatenation - " << endl; p1.print(); p2.print(); return 0; }
Output
Before concatenation - Prep Prep After concatenation - PrepInsta PrepChanging obj1 doesn’t reflect/cause any changes in obj2(Deep Copy)
Prime Course Trailer
Related Banners
Get PrepInsta Prime & get Access to all 200+ courses offered by PrepInsta in One Subscription
Get over 200+ course One Subscription
Courses like AI/ML, Cloud Computing, Ethical Hacking, C, C++, Java, Python, DSA (All Languages), Competitive Coding (All Languages), TCS, Infosys, Wipro, Amazon, DBMS, SQL and others
Login/Signup to comment