General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
| ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
Constructors are non-staticmember functions declared with a special declarator syntax, they are used to initialize objects of their class types.
A constructor cannot be acoroutine. | (since C++20) |
A constructor cannot have anexplicit object parameter. | (since C++23) |
Contents |
Constructors are declared using memberfunction declarators of the following form:
class-name( parameter-list (optional)) except (optional)attr (optional) | |||||||||
class-name | - | anidentifier expression, possibly followed by a list ofattributes, and(since C++11) possibly enclosed by a pair parentheses | ||||||
parameter-list | - | parameter list | ||||||
except | - |
| ||||||
attr | - | (since C++11) a list ofattributes |
The only specifiers allowed in thedeclaration specifiers of a constructor declaration arefriend
,inline
,constexpr
(since C++11),consteval
(since C++20), andexplicit
(in particular, no return type is allowed). Note thatcv- and ref-qualifiers are not allowed either: const and volatile semantics of an object under construction only kick in after the most-derived constructor completes.
The identifier expression ofclass-name must have one of the following forms:
The body of afunction definition of any constructor of classT
, before the opening brace of the compound statement, may include themember initializer list , whose syntax is the colon character:
, followed by the comma-separated list of one or moremember-initializer s, each of which has the following syntax:
memberinitializer | (1) | ||||||||
classinitializer | (2) | ||||||||
class-packinitializer... | (3) | (since C++11) | |||||||
| (since C++11) |
T
. In this case the corresponding base class subobject is direct-initialized withinitializer .member | - | an identifier that names a data member |
class | - | a class name |
class-pack | - | a pack that expands to zero or more classes |
initializer | - | aninitializer that does not begin with= |
struct S{int n; S(int);// constructor declaration S(): n(7){}// constructor definition:// ": n(7)" is the initializer list// ": n(7) {}" is the function body}; S::S(int x): n{x}{}// constructor definition: ": n{x}" is the initializer list int main(){ S s;// calls S::S() S s2(10);// calls S::S(int)}
Constructors have no names and cannot be called directly. They are invoked wheninitialization takes place, and they are selected according to the rules of initialization. The constructors withoutexplicit specifier areconverting constructors. The constructors with aconstexpr specifier make their type aliteral type. Constructors that may be called without any argument aredefault constructors. Constructors that take another object of the same type as the argument arecopy constructors andmove constructors.
Before the compound statement that forms the function body of the constructor begins executing, initialization of all direct bases, virtual bases, and non-static data members is finished. The member initializer list is the place where non-default initialization of these subobjects can be specified. For bases that cannot be default-initialized and for non-static data members that cannot be initialized by default-initialization or by theirdefault member initializer, if any(since C++11), such as members of reference and const-qualified types, member initializers must be specified.(Note that default member initializers for non-static data members of class template instantiations may be invalid if the member type or initializer is dependent.)(since C++11) No initialization is performed foranonymous unions orvariant members that do not have a member initializer or default member initializer(since C++11).
The initializers whereclass names a virtual base class are ignored during construction of any class that is not the most derived class of the object that is being constructed.
Names that appear ininitializer are evaluated in scope of the constructor:
class X{int a, b, i, j;public:constint& r; X(int i): r(a)// initializes X::r to refer to X::a , b{i}// initializes X::b to the value of the parameter i , i(i)// initializes X::i to the value of the parameter i , j(this->i)// initializes X::j to the value of X::i{}};
Exceptions that are thrown from member initializers may be handled by afunctiontry block.
If a non-static data member has adefault member initializer and also appears in a member initializer list, then the member initializer is used and the default member initializer is ignored: struct S{int n=42;// default member initializer S(): n(7){}// will set n to 7, not 42}; | (since C++11) |
Reference members cannot be bound to temporaries in a member initializer list:
struct A{ A(): v(42){}// Errorconstint& v;};
Note: same applies todefault member initializer.
Member functions (includingvirtual member functions) can be called for an object under construction or destruction. Similarly, an object under construction or destruction can be the operand oftypeid
ordynamic_cast
.
However, if these operations are performed during any of the following evaluations, the behavior is undefined:
| (since C++26) |
Delegating constructorIf the name of the class itself appears asclass-or-identifier in the member initializer list, then the list must consist of that one member initializer only; such a constructor is known as thedelegating constructor, and the constructor selected by the only member of the initializer list is thetarget constructor. In this case, the target constructor is selected by overload resolution and executed first, then the control returns to the delegating constructor and its body is executed. Delegating constructors cannot be recursive. class Foo{public: Foo(char x,int y){} Foo(int y): Foo('a', y){}// Foo(int) delegates to Foo(char, int)}; Inheriting constructors | (since C++11) |
The order of member initializers in the list is irrelevant, the actual order of initialization is as follows:
(Note: if initialization order was controlled by the appearance in the member initializer lists of different constructors, then thedestructor wouldn't be able to ensure that the order of destruction is the reverse of the order of construction.)
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_delegating_constructors | 200604L | (C++11) | Delegating constructors |
#include <fstream>#include <string>#include <mutex> struct Base{int n;}; struct Class:public Base{unsignedchar x;unsignedchar y;std::mutex m;std::lock_guard<std::mutex> lg;std::fstream f;std::string s; Class(int x): Base{123},// initialize base class x(x),// x (member) is initialized with x (parameter) y{0},// y initialized to 0 f{"test.cc", std::ios::app},// this takes place after m and lg are initialized s(__func__),// __func__ is available because init-list is a part of constructor lg(m),// lg uses m, which is already initialized m{}// m is initialized before lg even though it appears last here{}// empty compound statement Class(double a): y(a+1), x(y),// x will be initialized before y, its value here is indeterminate lg(m){}// base class initializer does not appear in the list, it is// default-initialized (not the same as if Base() were used, which is value-init) Class()try// function try block begins before the function body, which includes init list: Class(0.0)// delegate constructor{// ...}catch(...){// exception occurred on initialization}}; int main(){ Class c; Class c1(1); Class c2(0.1);}
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 194 | C++98 | the declarator syntax of constructor only allowed at most one function specifier (e.g. a constructor cannot be declaredinlineexplicit) | multiple function specifiers allowed |
CWG 257 | C++98 | it was unspecified whether an abstract class should provide member initializers for its virtual base classes | specified as not required and such member initializers are ignored during execution |
CWG 263 | C++98 | the declarator syntax of constructor prohibited constructors from being friends | allowed constructors to be friends |
CWG 1345 | C++98 | anonymous union members without default member initializers were default-initialized | they are not initialized |
CWG 1435 | C++98 | the meaning of “class name” in the declarator syntax of constructor was unclear | changed the syntax to a specialized function declarator syntax |
CWG 1696 | C++98 | reference members could be initialized to temporaries (whose lifetime would end at the end of constructor) | such initialization is ill-formed |