Explicitly Defaulted and Deleted Functions in C++ 11

Defaulted Function

What is a Defaulted Function?
Explicitly defaulted function declaration is a new form of function declaration that is introduced into the C++11 standard which allows you to append the ‘=default;’ specifier to the end of a function declaration to declare that function as an explicitly defaulted function. This makes the compiler generate the default implementations for explicitly defaulted functions, which are more efficient than manually programmed function implementations.

For example, whenever we declare a parameterized constructor, the compiler won’t create a default constructor. In such a case, we can use the default specifier in order to create a default one. The following code demonstrates how:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to demonstrate the
// use of defaulted functions
#include <iostream>
using namespace std;
  
class A {
public:
  
    // A user-defined 
    // parameterized constructor
    A(int x) 
    {
        cout << "This is a parameterized constructor";
    }
      
    // Using the default specifier to instruct
    // the compiler to create the default 
    // implementation of the constructor.
    A() = default
};
  
int main()
{
    // executes using defaulted constructor
    A a; 
      
    // uses parametrized constructor
    A x(1); 
    return 0;
}

chevron_right


Output:

This is a parameterized constructor

In the above case, we didn’t have to specify the body of the constructor A() because, by appending the specifier ‘=default’, the compiler will create a default implementation of this function.

What are constrains with making functions defaulted?
A defaulted function needs to be a special member function (default constructor, copy constructor, destructor etc), or has no default arguments. For example, the following code explains that non-special member functions can’t be defaulted:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to demonstrate that 
// non-special member functions 
// can't be defaulted
class B {
public:
  
    // Error, func is not a special member function.
    int func() = default
      
    // Error, constructor B(int, int) is not
    // a special member function.
    B(int, int) = default
  
    // Error, constructor B(int=0)
    // has a default argument.
    B(int = 0) = default
};
  
// driver program
int main()
{
    return 0;
}

chevron_right


What are the advantages of ‘=default’ when we could simply leave an empty body of the function using ‘{}’?
Even though the two may behave the same, there are still benefits of using default over leaving an empty body of the constructor. The following points explain how:

  1. Giving a user-defined constructor, even though it does nothing, makes the type not an aggregate and also not trivial. If you want your class to be an aggregate or a trivial type (or by transitivity, a POD type), then you need to use ‘= default’.
  2. Using ‘= default’ can also be used with copy constructor and destructors. An empty copy constructor, for example, will not do the same as a defaulted copy constructor (which will perform member-wise copy of its members). Using the ‘= default’ syntax uniformly for each of these special member functions makes code easier to read.

Deleted Function

Prior to C++ 11, the operator delete had only one purpose, to deallocate a memory that has been allocated dynamically.
The C++ 11 standard introduced another use of this operator, which is: To disable the usage of a member function. This is done by appending the =delete; specifier to the end of that function declaration.

Any member function whose usage has been disabled by using the ‘=delete’ specifier is known as an expicitly deleted function.

Although not limited to them, but this is usually done to implicit functions. The following examples exhibit some of the tasks where this feature comes handy:

Disabling copy constructors

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to disable the usage of
// copy-constructor using delete operator
#include <iostream>
using namespace std;
  
class A {
public:
    A(int x): m(x)
    {
    }
      
    // Delete the copy constructor
    A(const A&) = delete
      
    // Delete the copy assignment operator
    A& operator=(const A&) = delete
    int m;
};
  
int main()
{
    A a1(1), a2(2), a3(3);
      
    // Error, the usage of the copy
    // assignment operator is disabled
    a1 = a2;
      
    // Error, the usage of the
    // copy constructor is disabled
    a3 = A(a2); 
    return 0;
}

chevron_right


Disabling undesirable argument conversion

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to disable undesirable argument
// type conversion using delete operator
#include <iostream>
using namespace std;
  
class A {
public:
    A(int) {}
  
  
    // Declare the conversion constructor as a 
    // deleted function. Without this step, 
    // even though A(double) isn't defined, 
    // the A(int) would accept any double value 
    // for it's argumentand convert it to an int
    A(double) = delete
};
  
int main()
{
    A A1(1);
      
    // Error, conversion from 
    // double to class A is disabled.
    A A2(100.1); 
    return 0;
}

chevron_right


It is very important to note that A deleted function is implicitly inline. A deleted definition of a function must be the first declaration of the function. In other words, the following way is the correct way of declaring a function as deleted:

class C 
{
public:
         C(C& a) = delete;
};

But the following way of trying to declare a function deleted will produce an error:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Sample C++ code to demonstrate the 
// incorrect syntax of declaring a member 
// function as deleted
class
{
public:
    C();
};
  
// Error, the deleted definition  
// of function C must be the first 
// declaration of the function.
C::C() = delete

chevron_right


What are the advantages of explicitly deleting functions?

  1. Deleting of special member functions provides a cleaner way of preventing the compiler from generating special member functions that we don’t want. (As demonstrated in ‘Disabling copy constructors’ example).
  2. Deleting of normal member function or non-member functions prevents problematic type promotions from causing an unintended function to be called (As demonstrated in ‘Disabling undesirable argument conversion’ example).


My Personal Notes arrow_drop_up

Intern Technical Content Writing at GeeksforGeeks

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.