Explicitly Defaulted and Deleted Functions in C++ 11
Last Updated :
06 Jun, 2021
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:
CPP
// 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 parameterized constructor
A x(1);
return 0;
}
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:
CPP
// 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;
}
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:
- 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'.
- 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 explicitly 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
CPP
// 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;
}
Disabling undesirable argument conversion
CPP
// 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;
}
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:
CPP
// Sample C++ code to demonstrate the
// incorrect syntax of declaring a member
// function as deleted
class C
{
public:
C();
};
// Error, the deleted definition
// of function C must be the first
// declaration of the function.
C::C() = delete;
What are the advantages of explicitly deleting functions?
- 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).
- 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).
Similar Reads
functional::bad_function_call in C++ with Examples
Standard C++ contains several built-in exception classes, functional::bad_function_call is one of them. This is an exception thrown on bad call. Below is the syntax for the same: Header File: include<functional> Syntax: class bad_function_call; Note: To make use of functional::bad_function_cal
1 min read
Default Arguments and Virtual Function in C++
Default Arguments are the values provided during function declaration, such that values can be automatically assigned if no argument is passed to them. In case any value is passed the default value is overridden and it becomes a parameterized argument. Virtual function is a member function that is d
3 min read
Difference between user defined function and library function in C/C++
Library Functions These functions are the built-in functions i.e., they are predefined in the library of the C. These are used to perform the most common operations like calculations, updation, etc. Some of the library functions are printf, scanf, sqrt, etc. To use these functions in the program the
3 min read
deque::emplace_front() and deque::emplace_back() in C++ STL
Deque or Double-ended queues are sequence containers with the feature of expansion and contraction on both the ends. They are similar to vectors, but are more efficient in case of insertion and deletion of elements at the end, and also the beginning. Unlike vectors, contiguous storage allocation may
5 min read
C++ - Difference Between Functors and Functions
In C++, we have multiple options to operate over the data like in the case where we can use functions and functors. Although both seem to be similar in a few ways but have multiple differences between them. Let's check the differences between functions and functors in C++. What are functions? Functi
3 min read
exception::bad_exception in C++ with Examples
Standard C++ contains several built-in exception classes, exception::bad_exception is one of them. This is an exception thrown by unexpected handler. Below is the syntax for the same: Header File: include<exception> Syntax: class bad_exception; Return: The exception::bad_exception returns a nu
2 min read
Function Pointers and Callbacks in C++
A callback is a function that is passed as an argument to another function. In C++, we cannot directly use the function name to pass them as a callback. We use function pointers to pass callbacks to other functions, store them in data structures, and invoke them later. In this article, we will discu
2 min read
atexit() function in C/C++
The function pointed by atexit() is automatically called without arguments when the program terminates normally. In case more than one function has been specified by different calls to the atexit() function, all are executed in the order of a stack (i.e. the last function specified is the first to b
3 min read
Default Methods in C++ with Examples
If we write a class that has no methods in it, and the class does not inherit from another class, the compiler will add six methods to it automatically. The methods which can be automatically generated by the compiler are:Â Default Constructor: It is equivalent to an empty default constructor. The d
6 min read
delete and free() in C++
delete and free() in C++ have similar functionalities but they are different. In C++, the delete operator should only be used for deallocating the memory allocated either using the new operator or for a NULL pointer, and free() should only be used for deallocating the memory allocated either using m
2 min read