Constructors and member initializer lists

Constructors are non-static

member functions

declared with a special declarator syntax, they are used to initialize objects of their class types.

Syntax

Constructors are declared using member

function declarators

of the following form:

class-name(parameter-list(optional))except(optional)attr(optional)The only specifiers allowed in the

declaration specifiers

of a constructor declaration are

friend

,

inline

,

constexpr

(since C++11),

consteval

(since C++20), and

explicit

(in particular, no return type is allowed). Note that

cv- 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 of class-name must have one of the following forms:

In a

friend declaration

, the identifier expression is a

qualified identifier

that

names a constructor

.

Otherwise, in a member declaration that belongs to the

member specification

of a class or class template:

For classes, the identifier expression is the

injected-class-name

of the immediately-enclosing class.

For class templates, the identifier expression is a class name that names the

current instantiation

(until C++20)the injected-class-name(since C++20) of the immediately-enclosing class template.

Otherwise, the identifier expression is a qualified identifier whose terminal unqualified identifier is the injected-class-name of its

lookup

context.

Member initializer list

The body of a

function definition

of any constructor, before the opening brace of the compound statement, may include the member initializer list, whose syntax is the colon character :, followed by the comma-separated list of one or more member-initializer s, each of which has the following syntax:

class-or-identifier(expression-list(optional))(1) class-or-identifierbraced-init-list(2) (since C++11)parameter-pack...(3) (since C++11)class-or-identifier- any identifier that names a non-static data member or any type name which names either the class itself (for delegating constructors) or a direct or virtual base. expression-list- possibly empty, comma-separated list of the arguments to pass to the constructor of the base or member braced-init-list-

brace-enclosed initializer list

parameter-pack- name of a variadic template

parameter pack

Run this code

structS{intn;S(int);// constructor declarationS():n(7){}// constructor definition:// ": n(7)" is the initializer list// ": n(7) {}" is the function body};S::S(intx):n{x}{}// constructor definition: ": n{x}" is the initializer listintmain(){Ss;// calls S::S()Ss2(10);// calls S::S(int)}Explanation

Constructors have no names and cannot be called directly. They are invoked when

initialization

takes place, and they are selected according to the rules of initialization. The constructors without explicit specifier are

converting constructors

. The constructors with a constexpr specifier make their type a

literal type

. Constructors that may be called without any argument are

default constructors

. Constructors that take another object of the same type as the argument are

copy constructors

and

move 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 their

default 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 for

anonymous unions

or

variant members

that do not have a member initializer or default member initializer(since C++11).

The initializers where class-or-identifier names a

virtual base class

are ignored during construction of any class that is not the most derived class of the object that's being constructed.

Names that appear in expression-list or braced-init-list are evaluated in scope of the constructor:

classX{inta,b,i,j;public:constint&r;X(inti):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 a

function try block

.

If a non-static data member has a

default member initializer

and also appears in a member initializer list, then the member initializer is used and the default member initializer is ignored:

structS{intn=42;// default member initializerS():n(7){}// will set n to 7, not 42};(since C++11)Reference members cannot be bound to temporaries in a member initializer list:

structA{A():v(42){}// Errorconstint&v;};Note: same applies to

default member initializer

.

Operations during construction and destruction

Member functions (including

virtual member functions

) can be called for an object under construction or destruction. Similarly, an object under construction or destruction can be the operand of

typeid

or

dynamic_cast

.

However, if these operations are performed during any of the following evaluations, the behavior is undefined:

an evaluation of a member initializer list before all the member-initializer s for base classes have completed

Delegating constructor

If the name of the class itself appears as class-or-identifier in the member initializer list, then the list must consist of that one member initializer only; such a constructor is known as the delegating constructor, and the constructor selected by the only member of the initializer list is the target 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.

classFoo{public:Foo(charx,inty){}Foo(inty):Foo('a',y){}// Foo(int) delegates to Foo(char, int)};Inheriting constructors

See

using declaration

.

(since C++11)Initialization order

The order of member initializers in the list is irrelevant, the actual order of initialization is as follows:

1) If the constructor is for the most-derived class, virtual bases are initialized in the order in which they appear in depth-first left-to-right traversal of the base class declarations (left-to-right refers to the appearance in base-specifier lists).

2) Then, direct bases are initialized in left-to-right order as they appear in this class's base-specifier list.

3) Then, non-static data member are initialized in order of declaration in the class definition.

4) Finally, the body of the constructor is executed.

(Note: if initialization order was controlled by the appearance in the member initializer lists of different constructors, then the

destructor

wouldn't be able to ensure that the order of destruction is the reverse of the order of construction.)

Notes

Feature-test macroValueStdFeature

__cpp_delegating_constructors

200604L

(C++11)

Delegating constructors

Example

Run this code

#include<fstream>#include<string>#include<mutex>structBase{intn;};structClass:publicBase{unsignedcharx;unsignedchary;std::mutexm;std::lock_guard<std::mutex>lg;std::fstreamf;std::strings;Class(intx):Base{123},// initialize base classx(x),// x (member) is initialized with x (parameter)y{0},// y initialized to 0f{"test.cc",std::ios::app},// this takes place after m and lg are initializeds(__func__),// __func__ is available because init-list is a part of constructorlg(m),// lg uses m, which is already initializedm{}// m is initialized before lg even though it appears last here{}// empty compound statementClass(doublea):y(a+1),x(y),// x will be initialized before y, its value here is indeterminatelg(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}};intmain(){Classc;Classc1(1);Classc2(0.1);}Defect reports

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 declared inlineexplicit) 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 References

C++23 standard (ISO/IEC 14882:2024):

11.4.5 Constructors [class.ctor]

11.9.3 Initializing bases and members [class.base.init]

C++20 standard (ISO/IEC 14882:2020):

11.4.4 Constructors [class.ctor]

11.10.2 Initializing bases and members [class.base.init]

C++17 standard (ISO/IEC 14882:2017):

15.1 Constructors [class.ctor]

15.6.2 Initializing bases and members [class.base.init]

C++14 standard (ISO/IEC 14882:2014):

12.1 Constructors [class.ctor]

12.6.2 Initializing bases and members [class.base.init]

C++11 standard (ISO/IEC 14882:2011):

12.1 Constructors [class.ctor]

12.6.2 Initializing bases and members [class.base.init]

C++98 standard (ISO/IEC 14882:1998):

12.1 Constructors [class.ctor]

12.6.2 Initializing bases and members [class.base.init]

See also

copy elision

converting constructor

copy assignment

copy constructor

default constructor

destructor

explicit

initialization

aggregate initialization

constant initialization

copy initialization

default initialization

direct initialization

list initialization

reference initialization

value initialization

zero initialization

move assignment

move constructor

new