I have a question about the default constructor in C++. For example in a class A, what is the difference between using this default constructor A(){};
or A() = default;
? And what is the general difference between them?
Thank you in advance!
I have a question about the default constructor in C++. For example in a class A, what is the difference between using this default constructor A(){};
or A() = default;
? And what is the general difference between them?
Thank you in advance!
A constructor defined as defaulted on the first declaration is considered not user-provided. This is essentially like being implicit in C++03. Such a constructor declaration is allowed in an aggregate class.
struct ag {
ag() = default;
int a;
double b;
};
struct nag {
nag() {}
int a;
double b;
};
ag a = { 5, 12. }; // OK
nag na = { 5, 12. }; // error: not an aggregate and no appropriate constructor
This rule only applies when = default
appears inside the class. Given this class definition:
struct nag {
nag();
int a;
double b;
};
then these constructor definitions would indeed be completely equivalent:
nag::nag() {} // 1
nag::nag() = default; // 2
An explicit
default constructor usually disables empty copy-list-initialization syntax (= {}
), and {}
as an argument or return
value. An explicitly-defaulted and explicit
default constructor in an aggregate is confusingly exempt from this rule because aggregate initialization has higher precedence than constructor initialization. This provides a way to detect whether a class is an aggregate, but you probably should not do so.
struct sadistic {
explicit sadistic() = default;
// members
};
sadistic se = {}; // OK only if sadistic has no virtual functions, etc.
The behavior of the default constructors is the same for A() {}
and A() = default;
per 12.1p6:
The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.
The differences are:
constexpr
(an explicitly-defaulted constructor is constexpr
if that would be valid),For the last point:
#include <iostream>
struct A { int i; A() = default; };
struct B { int j; B() {} };
int main() {
int i = 42, j = 42;
new (&i) A();
new (&j) B();
std::cout << i << std::endl; // 0
std::cout << j << std::endl; // 42
}
So you might want to write a user-provided non-defaulted default constructor, if for example your class has trivial members that would be expensive to zero-initialize (e.g. a large array), but it's a very niche case.
There is not a lot of differences:
The old syntax (note that the ;
is not needed):
A() {}
is available since the first days of C++. It will default construct every base class and member variable.
The new C++11 syntax:
A() = default;
does exactly the same, but it is explicit about being default, so you (or the compiler) don't have to check if the braces are really empty.
Note that if a class have no declared constructors, the compiler will add one for you.
CORRECTION: There is a difference if the default constructor is deleted, that is, the class implicit default constructor is not valid. In this case the {}
is a syntax error, while the =default
is like a deleted definition:
struct S
{
int &r; //non default constructible
S() {} //error: uninitialized reference S::r;
S() = default; //ok: deleted constructor
S() = delete; //also ok (but not both!)
};