26 KiB
[class.ctor]
11 Classes [class]
11.4 Class members [class.mem]
11.4.5 Constructors [class.ctor]
11.4.5.1 General [class.ctor.general]
A declarator declares a constructor if it is a function declarator ([dcl.fct]) of the form
ptr-declarator ( parameter-declaration-clause ) noexcept-specifieropt attribute-specifier-seqopt
where the ptr-declarator consists solely of anid-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:
in a friend declaration ([class.friend]), the id-expression is a qualified-id that names a constructor ([class.qual]);
otherwise, in a member-declaration that belongs to themember-specification of a class or class template, the id-expression is the injected-class-name ([class.pre]) of the immediately-enclosing entity;
otherwise, theid-expression is a qualified-id whose unqualified-id is the injected-class-name of its lookup context.
Constructors do not have names.
In a constructor declaration, each decl-specifier in the optionaldecl-specifier-seq shall befriend,inline,constexpr,consteval, or an explicit-specifier.
[Example 1: struct S { S(); // declares the constructor};
S::S() { } // defines the constructor â end example]
A constructor is used to initialize objects of its class type.
[Note 1:
Because constructors do not have names, they are never found during unqualified name lookup; however an explicit type conversion using the functional notation ([expr.type.conv]) will cause a constructor to be called to initialize an object.
The syntax looks like an explicit call of the constructor.
â end note]
[Example 2: complex zz = complex(1,2.3); cprint( complex(7.8,1.2) ); â end example]
[Note 2:
For initialization of objects of class type see [class.init].
â end note]
An object created in this way is unnamed.
[Note 3:
[class.temporary] describes the lifetime of temporary objects.
â end note]
[Note 4:
Explicit constructor calls do not yield lvalues, see [basic.lval].
â end note]
[Note 5:
Some language constructs have special semantics when used during construction; see [class.base.init] and [class.cdtor].
â end note]
A constructor can be invoked for aconst,volatile orconstvolatile object.
const andvolatile semantics ([dcl.type.cv]) are not applied on an object under construction.
They come into effect when the constructor for the most derived object ([intro.object]) ends.
The address of a constructor shall not be taken.
[Note 6:
A return statement in the body of a constructor cannot specify a return value ([stmt.return]).
â end note]
A constructor shall not be a coroutine.
A constructor shall not have an explicit object parameter ([dcl.fct]).
11.4.5.2 Default constructors [class.default.ctor]
A default constructor for a class X is a constructor of class X for which each parameter that is not a function parameter pack has a default argument (including the case of a constructor with no parameters).
If there is no user-declared constructor or constructor template for classX, a non-explicit constructor having no parameters is implicitly declared as defaulted ([dcl.fct.def]).
An implicitly-declared default constructor is an inline public member of its class.
A defaulted default constructor for class X is defined as deleted if
any non-static data member with no default member initializer ([class.mem]) is of reference type,
X is a non-union class and any non-variant non-static data member of const-qualified type (or possibly multidimensional array thereof) with no brace-or-equal-initializer is not const-default-constructible ([dcl.init]),
any non-variant potentially constructed subobject, except for a non-static data member with a brace-or-equal-initializer, has class type M (or possibly multidimensional array thereof) and overload resolution ([over.match]) as applied to find M's corresponding constructor does not result in a usable candidate ([over.match.general]), or
any potentially constructed subobject S has class type M (or possibly multidimensional array thereof),M has a destructor that is deleted or inaccessible from the defaulted default constructor, and either S is non-variant or S has a default member initializer.
A default constructor for a class X istrivial if it is not user-provided and if
X has no virtual functions ([class.virtual]) and no virtual base classes ([class.mi]), and
no non-static data member of X has a default member initializer ([class.mem]), and
all the direct base classes of X have trivial default constructors, and
either X is a union or for all the non-variant non-static data members of X that are of class type (or array thereof), each such class has a trivial default constructor.
Otherwise, the default constructor isnon-trivial.
If a default constructor of a union-like class X is trivial, then for each union U that is either X or an anonymous union member of X, if the first variant member, if any, of U has implicit-lifetime type ([basic.types.general]), the default constructor of X begins the lifetime of that member if it is not the active member of its union.
[Note 1:
It is already the active member if U was value-initialized.
â end note]
Otherwise, an implicitly-defined ([dcl.fct.def.default]) default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with noctor-initializer ([class.base.init]) and an emptycompound-statement.
If that user-written default constructor would be ill-formed, the program is ill-formed.
If that user-written default constructor would be constexpr-suitable ([dcl.constexpr]), the implicitly-defined default constructor is constexpr.
Before the defaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and its non-static data members are implicitly defined.
[Note 2:
An implicitly-declared default constructor has an exception specification ([except.spec]).
An explicitly-defaulted definition might have an implicit exception specification, see [dcl.fct.def].
â end note]
[Note 3:
A default constructor is implicitly invoked to initialize a class object when no initializer is specified ([dcl.init.general]).
Such a default constructor needs to be accessible ([class.access]).
â end note]
[Note 4:
[class.base.init] describes the order in which constructors for base classes and non-static data members are called and describes how arguments can be specified for the calls to these constructors.
â end note]
11.4.5.3 Copy/move constructors [class.copy.ctor]
A non-template constructor for classX is a copy constructor if its first parameter is of typeX&,const X&,volatile X& orconst volatile X&, and either there are no other parameters or else all other parameters have default arguments ([dcl.fct.default]).
[Example 1:
X::X(const X&) andX::X(X&,int=1) are copy constructors.
struct X { X(int); X(const X&, int = 1);}; X a(1); // calls X(int); X b(a, 0); // calls X(const X&, int); X c = b; // calls X(const X&, int); â end example]
A non-template constructor for class X is a move constructor if its first parameter is of type X&&, const X&&,volatile X&&, or const volatile X&&, and either there are no other parameters or else all other parameters have default arguments ([dcl.fct.default]).
[Example 2:
Y::Y(Y&&) is a move constructor.
struct Y { Y(const Y&); Y(Y&&);};extern Y f(int); Y d(f(1)); // calls Y(Y&&) Y e = d; // calls Y(const Y&) â end example]
[Note 1:
All forms of copy/move constructor can be declared for a class.
[Example 3: struct X { X(const X&); X(X&); // OK X(X&&); X(const X&&); // OK, but possibly not sensible}; â end example]
â end note]
[Note 2:
If a classX only has a copy constructor with a parameter of typeX&, an initializer of typeconstX orvolatileX cannot initialize an object of typecv X.
[Example 4: struct X { X(); // default constructor X(X&); // copy constructor with a non-const parameter};const X cx; X x = cx; // error: X::X(X&) cannot copy cx into x â end example]
â end note]
A declaration of a constructor for a classX is ill-formed if its first parameter is of typecv X and either there are no other parameters or else all other parameters have default arguments.
A member function template is never instantiated to produce such a constructor signature.
[Example 5: struct S {template S(T); S();};
S g;
void h() { S a(g); // does not instantiate the member template to produce S::S(S);// uses the implicitly declared copy constructor} â end example]
If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defaulted ([dcl.fct.def]).
The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor ([depr.impldec]).
The implicitly-declared copy constructor for a classX will have the formX::X(const X&) if each potentially constructed subobject of a class typeM (or array thereof) has a copy constructor whose first parameter is of typeconstM& orconstvolatileM&.89
Otherwise, the implicitly-declared copy constructor will have the formX::X(X&)
If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if
X does not have a user-declared copy constructor,
X does not have a user-declared copy assignment operator,
X does not have a user-declared move assignment operator, and
X does not have a user-declared destructor.
[Note 3:
When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor might instead invoke a copy constructor.
â end note]
The implicitly-declared move constructor for class X will have the formX::X(X&&)
An implicitly-declared copy/move constructor is an inline public member of its class.
A defaulted copy/move constructor for a class X is defined as deleted ([dcl.fct.def.delete]) if X has:
a potentially constructed subobject of type M (or possibly multidimensional array thereof) for which overload resolution ([over.match]), as applied to find M's corresponding constructor, either does not result in a usable candidate ([over.match.general]) or, in the case of a variant member, selects a non-trivial function,
any potentially constructed subobject of class type M (or possibly multidimensional array thereof) where M has a destructor that is deleted or inaccessible from the defaulted constructor, or,
for the copy constructor, a non-static data member of rvalue reference type.
[Note 4:
A defaulted move constructor that is defined as deleted is ignored by overload resolution ([over.match], [over.over]).
Such a constructor would otherwise interfere with initialization from an rvalue which can use the copy constructor instead.
â end note]
A copy/move constructor for classX is trivial if it is not user-provided and if
classX has no virtual functions ([class.virtual]) and no virtual base classes ([class.mi]), and
the constructor selected to copy/move each direct base class subobject is trivial, and
for each non-static data member ofX that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;
otherwise the copy/move constructor isnon-trivial.
[Note 5:
The copy/move constructor is implicitly defined even if the implementation elided its odr-use ([basic.def.odr], [class.temporary]).
â end note]
If an implicitly-defined ([dcl.fct.def.default]) constructor would be constexpr-suitable ([dcl.constexpr]), the implicitly-defined constructor is constexpr.
Before the defaulted copy/move constructor for a class is implicitly defined, all non-user-provided copy/move constructors for its potentially constructed subobjects are implicitly defined.
[Note 6:
An implicitly-declared copy/move constructor has an implied exception specification ([except.spec]).
â end note]
The implicitly-defined copy/move constructor for a non-union classX performs a memberwise copy/move of its bases and members.
[Note 7:
Default member initializers of non-static data members are ignored.
â end note]
The order of initialization is the same as the order of initialization of bases and members in a user-defined constructor (see [class.base.init]).
Let x be either the parameter of the constructor or, for the move constructor, an xvalue referring to the parameter.
Each base or non-static data member is copied/moved in the manner appropriate to its type:
if the member is an array, each element is direct-initialized with the corresponding subobject of x;
if a member m has rvalue reference type T&&, it is direct-initialized withstatic_cast<T&&>(x.m);
otherwise, the base or member is direct-initialized with the corresponding base or member of x.
Virtual base class subobjects shall be initialized only once by the implicitly-defined copy/move constructor (see [class.base.init]).
The implicitly-defined copy/move constructor for a unionX copies the object representation ([basic.types.general]) of X.
For each object nested within ([intro.object]) the object that is the source of the copy, a corresponding object o nested within the destination is identified (if the object is a subobject) or created (otherwise), and the lifetime of o begins before the copy is performed.
This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to avolatile lvalue; see [diff.class].