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

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

Run
#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

Run
#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

Run
#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

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 –
Run
#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
PrepInsta
Any 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

Run
#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
Prep
Changing 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

Checkout list of all the video courses in PrepInsta Prime Subscription

Checkout list of all the video courses in PrepInsta Prime Subscription