Default constructors
A default constructor is a constructor which can be called with no arguments (either defined with an empty parameter list, or with default arguments provided for every parameter). A type with a public default constructor is DefaultConstructible.
Contents |
[edit] Syntax
ClassName ( ) ; | (1) | ||||||||
ClassName :: ClassName ( ) body | (2) | ||||||||
ClassName() = delete ; | (3) | (since C++11) | |||||||
ClassName() = default ; | (4) | (since C++11) | |||||||
[edit] Explanation
ClassName is the identifier of the enclosing class
The default constructors are called when:
- creating objects or arrays of static, thread-local, and automatic storage duration that are declared without an initializer, (T obj; or T arr[10];)
- creating objects of dynamic storage duration when the new-expression is written without an initializer (new T;)
- creating arrays of dynamic storage duration with the expression new T[n]
- creating value-initialized temporary objects with the cast expression T().
[edit] Implicitly-declared default constructor
If no user-defined constructors of any kind are provided for a class type (struct, class, or union), the compiler will always declare a default constructor as an inline public member of its class. If some user-defined constructors are present, the user may still force the generation of the implicitly declared constructor with the keyword default (since C++11).
[edit] Deleted implicitly-declared default constructor
The implicitly-declared or defaulted default constructor for class T is undefined (until C++11) / defined as deleted (since C++11) in any of the following is true:
- T has a member of reference type (without a brace-or-equal initializer(since C++11)).
- T has a const member (without a brace-or-equal initializer(since C++11)) or a user-defined default constructor.
- T has a member (without a brace-or-equal initializer(since C++11)), which has a deleted default constructor, or its default constructor is ambiguous or inaccessible from this constructor.
- T has a direct or virtual base which has a deleted default constructor, or it is ambiguous or inaccessible from this constructor.
- T has a direct or virtual base which has a deleted destructor, or a destructor that is inaccessible from this constructor.
- T is a union with at least one variant member with non-trivial default constructor(since C++11).
- T is a union and all of its variant members are const.
[edit] Trivial default constructor
The implicitly-declared default constructor for class T is trivial if all of the following is true:
- T has no virtual member functions
- T has no virtual base classes
- T has no non-static members with brace-or-equal initializers (since C++11)
- Every direct base of T has a trivial default constructor
- Every non-static member of class type has a trivial default constructor
A trivial default constructor is a constructor that performs no action. Objects with trivial default constructors can be created by using reinterpret_cast on any storage, e.g. on memory allocated with std::malloc. All data types compatible with the C language (POD types) are trivially default-constructible.
[edit] Implicitly-defined default constructor
If the implicitly-declared default constructor is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler, and it has exactly the same effect as a user-defined constructor with empty body and empty initializer list. That is, it calls the default constructors of the bases and of the non-static members of this class.
[edit] Example
struct A { int x; A(int x = 1) : x(x) {} // user-defined default ctor }; struct B : A { // B::B() is implicitly-defined, calls A::A() }; struct C { A obj; // C::C() is implicitly-defined, calls A::A() }; struct D : A { D(int y) : A(y) {} // D::D() is not declared because another constructor exists }; struct E : A { E(int y) : A(y) {} E() = default; // explicitly defaulted, calls A::A() }; struct F { int& ref; // reference member const int c; // const member // Bad::Bad() is deleted }; int main() { A a; B b; // D d; // compile error E e; // F f; // compile error }