Delete default constructor in C++

Do not miss this exclusive book on Binary Tree Problems. Get it now for free.

In this article, we have explored how to delete the default constructor in C++ Programming Language using different C++ code examples.

Table of content

  1. Introduction
  2. Ways to delete

1. Introduction

As we could see in this article, a default constructor is a member function of a class that it has been declared without any parameters or if it has ones they must be with some default values.
If programmer forgets to declare one, the compiler will create one implicitly.

Before we would like to delete the default constructor we must first see how this it is declared.

    A(){};

    A(int a = 0 ){};

    A() = default; //since C++11

The all 3 expresions are echivalent and can be implemented only once in the body of a class ! If you will implement 2 of them an overloading compilation error you will get.

Notice that the call in the main body of the next expression:

    A a();

will not call the default constructor but represents a simple function declaration ! wich takes no arguments and return an object of type A.

The corect call for the default constructor will be:

    A a;

and it is called at the declaration of the object a with no initialization of any arguments.
Ex.

    #include <iostream>

    using namespace std;

    class A
    {
    public:
        //A(){};
        A(int a=0){cout<<"default"<<endl;};
        //A() = default  ;
    };

    int main()
    {
        int x;
        A a;               //default constructor is called
        A b(x);            //default constructor is called
        A c();             //simple function declaration
        A *d;              //simple pointer variable of type A
        A *e = new A;      //default constructor is called only once
        A *f = new A[3];   //default constructor is called 3 times 
        return 0;
    }

Output:

default
default
default
default
default
default

Notice that

    A (int a); 

is not a declaration of a default constructor but a user defined one which in absence of a default constructor declaration an instantiation of an object of type A

    A a;

will generate an error since the compiler will not generate an implicit default constructor !

2. Ways to delete

We saw earlier how a default constructor is declared but how we can delete it ?

The biggest confusion is to use the =delete option which for some reasons compiler authors called delete instead of disable which in fact that is what is doing, i.e. it disables that constructor or function to be used by that object.

For example if we want not to use the assignement operator nor the default constructor we can achieve that by doing this:

    class A
        {
            public:
                A(int a=0) = delete;
                A& operator = (const A&) = delete;
        }

Then if we would like to instantiate the object we will get a compilation error:

A a;

error: use of deleted function ‘A::A(int)’

or

a=b;

error: use of deleted function ‘A& A::operator=(const A&)’

When we refer to delete an object it means we would like to dealocate the memory assigned to it.

In C++ an object allocated dynamically (with new) is deleted using the delete operator if it has only one instance or delete [] if there are many, i.e. an array of instances of that type.

A *e = new A;
delete e;

A *f = new A[3];
delete[] f;

Remember that delete operator is only called with new operator. So what happens if will have a pointer as a member of our class ? We can allocate memory for it in the default constructor but we would need also to dealocate after that.

To do so we will need to implement the default destructor.

    class A
        {
        int *v;
        
        public:
            A(){ v = new int; cout<<"allocate v"<<endl;}
            ~A(){ delete v; cout<<"deallocate v"<<endl;}
        };
        
     int main()
     {
        A a;               //default constructor is called
        A c();             //simple function declaration
        A *d;              //simple pointer variable of type A
        A *e = new A;      //default constructor is called only once
        delete e;          //default destructor is called once  
        A *f = new A[3];   //default constructor is called 3 times
        delete[] f;        //default destructor is called 3 times
        
        return 0;
     }   

Output:

allocate v //the output for object a
allocate v //the output for object e
deallocate v //the output for deallocation of e
allocate v //the output for object f[0]
allocate v //the output for object f[1]
allocate v //the output for object f[2]
deallocate v //the output for deallocation of f[2]
deallocate v //the output for deallocation of f[1]
deallocate v //the output for deallocation of f[0]
deallocate v //the output for deallocation of a

Notice the deallocation of the object a at the end of the program, and that is because it's lifetime was until the main was ending.

Obs. If we forget to call the delete operator for the objects e and f the default destructor will not be called for them and there will be no deallocation memory !

We can use another constructor to initialize our member.

    #include <iostream>

    using namespace std;

    class A
    {
        int *v;
    public:
        
        A() { v = new int; cout<<"allocate v"<<endl;}
        A(int n) {v= new int; v=&n; cout<<*v<<endl;}
        
        ~A() { delete v; cout<<"deallocate v"<<endl;}  
        
        
    };

    int main()
    {
        int n=5;
        A a;               //default constructor is called
        A b(n);            //initialization constructor is called    
       
        return 0;
    }

Output:

allocate v
5
free(): invalid pointer

To avoid the free():invalid pointer runtime error we can use A(int n) {v= new int(n); cout<<*v<<endl;}. This is demonstrated in the following C++ code example.

In the fixed version (v= new int(n)), we are creating a new int object using the value of n. This is completely different from n.

In the original version, we are creating a new int object first but then, overwriting it with the address of n so it is same as n.

    #include <iostream>

    using namespace std;

    class A
    {
        int *v;
    public:
        
        A() { v = new int; cout<<"allocate v"<<endl;}
        A(int n) : v(new int(n)) { cout<<*v<<endl;}
        
        ~A() { delete v; cout<<"deallocate v"<<endl;}  
        
        
    };

    int main()
    {
        int n=5;
        A a;               //default constructor is called
        A b(n);            //initialization constructor is called    
       
        return 0;
    }

Output:

allocate v
5
deallocate v
deallocate v

Notice that deallocation is in LIFO order.

With this article at OpenGenus, you must have the complete idea of deleting default constructor in C++.

Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.