What does "default" mean after a class' function declaration?
I've seen default
used next to function declarat开发者_运维技巧ions in a class. What does it do?
class C {
C(const C&) = default;
C(C&&) = default;
C& operator=(const C&) & = default;
C& operator=(C&&) & = default;
virtual ~C() { }
};
It's a new C++11 feature.
It means that you want to use the compiler-generated version of that function, so you don't need to specify a body.
You can also use = delete
to specify that you don't want the compiler to generate that function automatically.
With the introduction of move constructors and move assignment operators, the rules for when automatic versions of constructors, destructors and assignment operators are generated has become quite complex. Using = default
and = delete
makes things easier as you don't need to remember the rules: you just say what you want to happen.
This is a new C++0x feature that tells the compiler to create the default version of the respective constructor or assignment operator, i.e. the one which just performs the copy or move action for each member. This is useful because the move constructor isn't always generated by default (e.g. if you have a custom destructor), unlike the copy constructor (and likewise for assignment), but if there's nothing non-trivial to write, it's better to let the compiler handle it than to spell it out yourself each time.
Also notice that a default constructor would not be generated if you provide any other non-default constructor. If you still want the default constructor, too, you can use this syntax to have the compiler make one.
As another use case, there are several situations in which a copy constructor would not be generated implicitly (e.g. if you provide a custom move constructor). If you still want the default version, you can request it with this syntax.
See Section 12.8 of the standard for details.
It is new in C++11, see here. It can be quite useful if you have defined one constructor, but want to use defaults for the others. Pre-C++11 you'd have to define all constructors once you have defined one, even if they are equivalent to the defaults.
Also note that in certain situations it is impossible to provide a user defined default constructor that behaves the same as the compiler synthesized one under both default and value initialization. default
allows you to get that behaviour back.
Another use case that I do not see mentioned in these answers is that it easily allows you to change the visibility of a constructor. For example, maybe you want a friend class to be able to access the copy constructor, but you don't want it to be publicly available.
C++17 N4659 standard draft
https://github.com/cplusplus/draft/blob/master/papers/n4659.pdf 11.4.2 "Explicitly-defaulted functions":
1 A function definition of the form:
attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt = default ;
is called an explicitly-defaulted definition. A function that is explicitly defaulted shall
(1.1) — be a special member function,
(1.2) — have the same declared function type (except for possibly differing ref-qualifiers and except that in the case of a copy constructor or copy assignment operator, the parameter type may be “reference to non-const T”, where T is the name of the member function’s class) as if it had been implicitly declared, and
(1.3) — not have default arguments.
2 An explicitly-defaulted function that is not defined as deleted may be declared constexpr only if it would have been implicitly declared as constexpr. If a function is explicitly defaulted on its first declaration, it is implicitly considered to be constexpr if the implicit declaration would be.
3 If a function that is explicitly defaulted is declared with a noexcept-specifier that does not produce the same exception specification as the implicit declaration (18.4), then
(3.1) — if the function is explicitly defaulted on its first declaration, it is defined as deleted;
(3.2) — otherwise, the program is ill-formed.
4 [ Example:
struct S { constexpr S() = default; // ill-formed: implicit S() is not constexpr S(int a = 0) = default; // ill-formed: default argument void operator=(const S&) = default; // ill-formed: non-matching return type ~ S() noexcept(false) = default; // deleted: exception specification does not match private: int i; // OK: private copy constructor S(S&); }; S::S(S&) = default; // OK: defines copy constructor
— end example ]
5 Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them (15.1 15.4, 15.8), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. [ Note: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note ]
6 [ Example:
struct trivial { trivial() = default; trivial(const trivial&) = default; trivial(trivial&&) = default; trivial& operator=(const trivial&) = default; trivial& operator=(trivial&&) = default; ~ trivial() = default; }; struct nontrivial1 { nontrivial1(); }; nontrivial1::nontrivial1() = default; // not first declaration
— end example ]
Then the question is of course which functions can be implicitly declared and when does that happen, which I have explained at:
- What is the <=> ("spaceship", three-way comparison) operator in C++?
- What are all the member-functions created by compiler for a class? Does that happen all the time?
- Conditions for automatic generation of default/copy/move ctor and copy/move assignment operator?
精彩评论