Default functions in C++11
Do not miss this exclusive book on Binary Tree Problems. Get it now for free.
C++11 introduced a new use of the default
keyword as a way to explicitly tell the compiler that a special member function will use the default implementation.
Introduction
Functions are a set of statements put together that perform a specific task. Member functions include the operators and functions that are members of a class. While the user has to provide these member functions, the compiler generates some of the functions which are known as special member functions.
The special member functions that are generated automatically are: the default constructor, copy constructor and move constructor, copy assignment operator and move assignment operator and a destructor.
In C++11 these special member functions are the only functions that can be defaulted, that is, defined using =default
instead of the function body. From C++20 additionally the comparison operators can also be defaulted.
Pre C++11
There are various rules according to which the compiler may or may not automatically generate the special member functions.
If any constructor is declared, then no default constructor is automatically generated. If a destructor is declared, then no default destructor is automatically generated.
If a move constructor or move-assignment operator is explicitly declared, then:
Copy constructor and copy-assignment operator are not automatically generated.
If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is declared, then both the move constructor and move-assignment operator are not automatically generated.
Once the defaults are suppressed there is no way to reinstantiate them.
default
functions
In C++11, a special member function can be explicitly defined to use the default implementation. The way to do this is to append a =default
to the end of the special member function declaration. For example
class foo{
foo()=default;
};
The =default;
is thus part of the special member function definition. This allows us to have the performance benifits of the trivial special member functions with less effort, given that it is what we want.
Example usage
Default constructor
class X{
private:
int a;
};
X x; // OK, compiler implicitly-defined default constructor is called
class Y{
public:
Y(int i){
a = i;
}
private:
int a;
};
Y y; // error, default constructor Y::Y() doesn't exist
class Z{
public:
Z()=default; // default
Z(int i){ // user defined constructor
a = i;
}
private:
int a;
};
Z z; // OK
Z z2(4); // OK
The code above shows three examples. In the first example class X
, no user-defined constructor is provided so the compiler will auto-generate a default constructor that will not take any parameters. In the second example class Y
, the compiler will not auto-generate a default constructor, since a user defined constructor is provided. In the third class Z
, although the compiler will not provide a default constructor, we can tell it to provide the default implementation to it by using the =default
keyword.
Use a standard-defined equality operator
Note that the following works in C++20.
While the equalty operator is not implicitly defined, there is a standard-defined. Here the equality operator compares each data member and determines if they are equal. Two objects are equal if their corresponding members are equal.
consider an example:
#include <iostream>
struct point {
int x;
int y;
bool operator==(const point&) const = default;
};
int main() {
point p1{1, 2}, p2{3, 4};
if(p1 == p2){
std::cout << "equal" << std::endl;
}
else{
std::cout << "unequal" << std::endl;
}
}
Conclusion
Use of =default
allows an explicit way to express as to which of the functions should be automatically provided with default implementation, even if it was stopped from getting one. This is useful when we want to explicitly state that we want to use the default implementation for a special member function.
Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.