Constructors and member initializer lists

Constructor is a special non-static member function of a class that is used to initialize objects of its class type.

In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual base subobjects and non-static data members. ( Not to be confused with std::initializer_list )

[ edit ] Syntax

Constructors are declared using member function declarators of the following form:

Where class-name must name the current class (or current instantiation of a class template), or, when declared at namespace scope or in a friend declaration, it must be a qualified class name.

The only specifiers allowed in the decl-specifier-seq of a constructor declaration are friend , inline , explicit and constexpr (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 don't kick in until the most-derived constructor completes.

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-initializers , each of which has the following syntax

[ edit ] 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 LiteralType . 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. Member initializer list is the place where non-default initialization of these objects can be specified. For members that cannot be default-initialized, such as members of reference and const-qualified types, member initializers must be specified.

The initializers where class-or-identifier names a virtual base class are ignored during execution of constructors of any class that is not the most derived class of the object that's being constructed.

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

Exceptions that are thrown from member initializers may be handled by function-try-block

Member functions (including virtual member functions) can be called from member initializers, but the behavior is undefined if not all direct bases are initialized at that point.

For virtual calls (if the bases are initialized), the same rules apply as the rules for the virtual calls from constructors and destructors: virtual member functions behave as if the dynamic type of * this is the class that's being constructed (dynamic dispatch does not propagate down the inheritance hierarchy) and virtual calls (but not static calls) to pure virtual member functions are undefined behavior.

[ edit ] Initialization order

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 the destructor wouldn't be able to ensure that the order of destruction is the reverse of the order of construction)

[ edit ] Example

[ edit ] references.

  • 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):

Initializer list

( Not to be confused with std::initializer_list ) They are the part of a constructor which is responsible for member and ancestor initialization

[ edit ] Syntax

[ edit ] explanation.

The initializer list is the place where initialization of the object should occur, there is where the constructors for base classes and members are called. Members are initialized in the same order as they are declared, not as they appear in the initializer list.

If a parameter in the constructor has the same name as one of the members, the ambiguity of that identifier being passed in a constructor call inside the intializer list is resolved choosing the parameter (and not the member).

Members or base classes not present in the list will be default constructed

[ edit ] Example

  • C++ Data Types
  • C++ Input/Output
  • C++ Pointers
  • C++ Interview Questions
  • C++ Programs
  • C++ Cheatsheet
  • C++ Projects
  • C++ Exception Handling
  • C++ Memory Management
  • C++ default constructor | Built-in types for int(), float, double()
  • Templates and Default Arguments
  • Integer literal in C/C++ (Prefixes and Suffixes)
  • Convert C/C++ program to Preprocessor code
  • How does 'void*' differ in C and C++?
  • const_cast in C++ | Type Casting operators
  • Hiding of all Overloaded Methods with Same Name in Base Class in C++
  • When should we write our own assignment operator in C++?
  • Conversion Operators in C++
  • Incompatibilities between C and C++ codes
  • Socket Programming in C/C++: Handling multiple clients on server without multi threading
  • When are Constructors Called?
  • Amazing stuff with system() in C / C++
  • Assertions in C/C++
  • Exception Handling and Object Destruction in C++
  • Quine - A self-reproducing program
  • Program to print last 10 lines
  • Use of explicit keyword in C++
  • Default Assignment Operator and References in C++

When do we use Initializer List in C++?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

The above code is just an example for syntax of the Initializer list. In the above code, x and y can also be easily initialed inside the constructor. But there are situations where initialization of data members inside constructor doesn’t work and Initializer List must be used. The following are such cases:

1. For Initialization of Non-Static const Data Members

const data members must be initialized using Initializer List. In the following example, “t” is a const data member of Test class and is initialized using Initializer List. Reason for initializing the const data member in the initializer list is because no memory is allocated separately for const data member, it is folded in the symbol table due to which we need to initialize it in the initializer list. 

Also, it is a Parameterized constructor and we don’t need to call the assignment operator which means we are avoiding one extra operation.

2. For Initialization of Reference Members

Reference members must be initialized using the Initializer List. In the following example, “t” is a reference member of the Test class and is initialized using the Initializer List.

3. For Initialization of Member Objects that do not have a Default Constructor

In the following example, an object “a” of class “A” is a data member of class “B”, and “A” doesn’t have a default constructor. Initializer List must be used to initialize “a”.

If class A had both default and parameterized constructors, then Initializer List is not a must if we want to initialize “a” using the default constructor, but it is must to initialize “a” using the parameterized constructor. 

4. For Initialization of Base Class Members

Like point 3, the parameterized constructor of the base class can only be called using the Initializer List.

5. When the Constructor’s Parameter Name is the Same as Data Member

If the constructor’s parameter name is the same as the data member name then the data member must be initialized either using this pointer or Initializer List. In the following example, both the member name and parameter name for A() is “i”.

6. For Performance Reasons

It is better to initialize all class variables in the Initializer List instead of assigning values inside the body. Consider the following example:

Here compiler follows following steps to create an object of type MyClass 

1. Type’s constructor is called first for “a”. 

2. Default construct “variable”

3. The assignment operator of “Type” is called inside body of MyClass() constructor to assign 

4. And then finally destructor of “Type” is called for “a” since it goes out of scope.

Now consider the same code with MyClass() constructor with Initializer List

With the Initializer List, the following steps are followed by compiler: 

1. Type’s constructor is called first for “a”.  2. Parameterized constructor of “Type” class is called to initialize: variable(a). The arguments in the initializer list are used to copy construct “variable” directly.  3. The destructor of “Type” is called for “a” since it goes out of scope.

As we can see from this example if we use assignment inside constructor body there are three function calls: constructor + destructor + one addition assignment operator call. And if we use Initializer List there are only two function calls: copy constructor + destructor call. See this post for a running example on this point.

This assignment penalty will be much more in “real” applications where there will be many such variables. Thanks to ptr for adding this point. 

Parameter vs Uniform Initialization in C++

It is better to use an initialization list with uniform initialization {} rather than parameter initialization () to avoid the issue of narrowing conversions and unexpected behavior. It provides stricter type-checking during initialization and prevents potential narrowing conversions

Code using parameter initialization () 

In the above code, the value 300 is out of the valid range for char, which may lead to undefined behavior and potentially incorrect results. The compiler might generate a warning or error for this situation, depending on the compilation settings.

Code using uniform initialization {}

By using uniform initialization with {} and initializing x with the provided value a, the compiler will perform stricter type-checking and issue a warning or error during compilation, indicating the narrowing conversion from int to char. Here is code with uniform initialization {} , which results in a warning and thus better to use

Please Login to comment...

Similar reads.

  • 10 Best Slack Integrations to Enhance Your Team's Productivity
  • 10 Best Zendesk Alternatives and Competitors
  • 10 Best Trello Power-Ups for Maximizing Project Management
  • Google Rolls Out Gemini In Android Studio For Coding Assistance
  • 30 OOPs Interview Questions and Answers (2024)

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

  • Memory Ordering
  • project-managment

list initialization and std::initializer_list

March 09, 2019.

Reading time ~5 minutes

List initialization, since C++11

Initializer list, usage of std::initializer_list, explicitly declare type/use of initializer_list for template, c++, c++11, initializer_list, emplace, emplace_back, list initialization.

time: 2019-03-10-Sun 02:29:50

List initialization is a “new” syntax support (sugar) since C++11, the main idea is to initialize object with a given list of arguments in enclosed brace for initialization.

direct-list-initialization

copy-list-initialization

The rule is simple, order of arguments in braced-init-list match the corresponding constructor’s, compiler will pick the ctor according the given list.

For POD type (pure struct), there will be a default list-initialization constructor which tasks arguments as the member variable.

Note that a braced-init-list is not an expression and therefore has no type , e.g. decltype({1,2}) is ill-formed, it can not be deduced when using a template.

For more explanation of list initialization , check this site

With this syntax support we can initialize a std::pair<std::string, int>

to initialize a std::vector<std::pair<std::string, int>> as

However, we can simplify initialization of std::vector<std::pair<std::string, int>> not only with help of list-initialization but also with help of std::initializer_list .

An object of type std::initializer_list is a lightweight proxy object that provides access to an array of objects of type const T. A std::initializer_list object is automatically constructed when: a braced-init-list is used to list-initialize an object, where the corresponding constructor accepts an std::initializer_list parameter a braced-init-list is used as the right operand of assignment or as a function call argument, and the corresponding assignment operator/function accepts an std::initializer_list parameter a braced-init-list is bound to auto, including in a ranged for loop Initializer lists may be implemented as a pair of pointers or pointer and length. Copying a std::initializer_list does not copy the underlying objects.

The initializer_list template only accepts a type T , it’s usually used for container initialization.

std::vector has a constructor of std::initlizaer_list , possible initialization is

Essentially, std::initializer_list is a list of arguments we want to pass, the number of elements in initializer list is not fixed.

We can iterate the list over with iterator or range-for

One more thing to say, e.g., there is a declaration

foo(1) and foo({1}) is the same to call that function, however this will cause gcc or clang to warn

You should remove the braces: { and } around single value, gcc/clang thinks it is verbose to do that for a single scalar type.

And the priority for matching is the same as that for overloading.

It’s not ambiguous, a call of Foo(std::string) will match ctor3 exactly, no warning.

The emplace or emplace_back for containers take arbitrary arguments for the element type constructor.

The common implementation, gcc or clang, is following (pseudo code)

There is an arguments forwarding, if we write down something like the following, the compiler will be confused when deduce the template for constructor, it keeps the {} thing, raw initialize_list <brace-enclosed initializer list> , all through the deduction, it has no type , which will not make any sense for deduction.

The simple one

or, there is a more complicated one

We should explicitly “declare” what the <brace-enclosed initializer list> is in the template function, be aware of that the following statements are not type cast , it’s just like a “declaration” to specify the type/use of that initializer list.

The following is kind of “decalaration”, decalaring that <brace-enclosed initializer list> is a certain type.

The above code can be simply written as

Apparently, the following wont compile, it’s a syntax error, because {...} is being deduced without any context (type info), which will certainly fail.

  • list initialization is convenient for use
  • raw initializer list, A.K.A, braced-init-list has no type
  • do not pass a braced-init-list for template deduction, “assign” (declare) it a “type” explicitly
  • passing std::initializer_list by value is very cheap, don’t worry about performance

https://stackoverflow.com/questions/24550924/emplacement-of-a-vector-with-initializer-list https://en.cppreference.com/w/cpp/language/list_initialization https://en.cppreference.com/w/cpp/utility/initializer_list

从 shared_from_this() 谈智能指针 weak_ptr 和 shared_ptr 的实现

一般来说c++ `shared_ptr` 实现逻辑上基本上都是一个ptr加上一个control block来实现,control block 用于保存引用计数以及如何回收(deleter)等信息,有一些实现(gcc)会将ptr放到control block里,有的(llvm...… Continue reading

braft call graph

Clock and timestamp.

Learn C++

14.10 — Constructor member initializer lists

This lesson continues our introduction of constructors from lesson 14.9 -- Introduction to constructors .

Member initialization via a member initialization list

To have a constructor initialize members, we do so using a member initializer list (often called a “member initialization list”). Do not confuse this with the similarly named “initializer list” that is used to initialize aggregates with a list of values.

Member initialization lists are something that is best learned by example. In the following example, our Foo(int, int) constructor has been updated to use a member initializer list to initialize m_x , and m_y :

The member initializer list is defined after the constructor parameters. It begins with a colon (:), and then lists each member to initialize along with the initialization value for that variable, separated by a comma. You must use a direct form of initialization here (preferably using braces, but parentheses works as well) -- using copy initialization (with an equals) does not work here. Also note that the member initializer list does not end in a semicolon.

This program produces the following output:

When foo is instantiated, the members in the initialization list are initialized with the specified initialization values. In this case, the member initializer list initializes m_x to the value of x (which is 6 ), and m_y to the value of y (which is 7 ). Then the body of the constructor runs.

When the print() member function is called, you can see that m_x still has value 6 and m_y still has value 7 .

Member initializer list formatting

C++ provides a lot of freedom to format your member initializer lists as you prefer, as it doesn’t care where you put your colon, commas, or whitespace.

The following styles are all valid (and you’re likely to see all three in practice):

Our recommendation is to use the third style above:

  • Put the colon on the line after the constructor name, as this cleanly separates the member initializer list from the function prototype.
  • Indent your member initializer list, to make it easier to see the function names.

If the member initialization list is short/trivial, all initializers can go on one line:

Otherwise (or if you prefer), each member and initializer pair can be placed on a separate line (starting with a comma to maintain alignment):

Member initialization order

Because the C++ standard says so, the members in a member initializer list are always initialized in the order in which they are defined inside the class (not in the order they are defined in the member initializer list).

In the above example, because m_x is defined before m_y in the class definition, m_x will be initialized first (even if it is not listed first in the member initializer list).

Because we intuitively expect variables to be initialized left to right, this can cause subtle errors to occur. Consider the following example:

In the above example, our intent is to calculate the larger of the initialization values passed in (via std::max(x, y) and then use this value to initialize both m_x and m_y . However, on the author’s machine, the following result is printed:

What happened? Even though m_y is listed first in the member initialization list, because m_x is defined first in the class, m_x gets initialized first. And m_x gets initialized to the value of m_y , which hasn’t been initialized yet. Finally, m_y gets initialized to the greater of the initialization values.

To help prevent such errors, members in the member initializer list should be listed in the order in which they are defined in the class. Some compilers will issue a warning if members are initialized out of order.

Best practice

Member variables in a member initializer list should be listed in order that they are defined in the class.

It’s also a good idea to avoid initializing members using the value of other members (if possible). That way, even if you do make a mistake in the initialization order, it shouldn’t matter because there are no dependencies between initialization values.

Member initializer list vs default member initializers

Members can be initialized in a few different ways:

  • If a member is listed in the member initializer list, that initialization value is used
  • Otherwise, if the member has a default member initializer, that initialization value is used
  • Otherwise, the member is default initialized.

This means that if a member has both a default member initializer and is listed in the member initializer list for the constructor, the member initializer list value takes precedence.

Here’s an example showing all three initialization methods:

On the author’s machine, this output:

Here’s what’s happening. When foo is constructed, only m_x appears in the member initializer list, so m_x is first initialized to 6 . m_y is not in the member initialization list, but it does have a default member initializer, so it is initialized to 2 . m_z is neither in the member initialization list, nor does it have a default member initializer, so it is default initialized (which for fundamental types, means it is left uninitialized). Thus, when we print the value of m_z , we get undefined behavior.

Constructor function bodies

The bodies of constructors functions are most often left empty. This is because we primarily use constructor for initialization, which is done via the member initializer list. If that is all we need to do, then we don’t need any statements in the body of the constructor.

However, because the statements in the body of the constructor execute after the member initializer list has executed, we can add statements to do any other setup tasks required. In the above examples, we print something to the console to show that the constructor executed, but we could do other things like open a file or database, allocate memory, etc…

New programmers sometimes use the body of the constructor to assign values to members:

Although in this simple case this will produce the expected result, in case where members are required to be initialized (such as for data members that are const or references) assignment will not work.

Prefer using the member initializer list to initialize your members over assigning values in the body of the constructor.

Question #1

Write a class named Ball. Ball should have two private member variables, one to hold a color, and one to hold a radius. Also write a function to print out the color and radius of the ball.

The following sample program should compile:

and produce the result:

Show Solution

Question #2

Why did we make print() a non-member function instead of a member function?

The rationale for this is given in lesson 14.8 -- The benefits of data hiding (encapsulation) .

Question #3

Why did we make m_color a std::string instead of a std::string_view ?

In this particular example, it doesn’t matter (because our color arguments are C-style string literals, which doesn’t go out of scope).

But conceptually, we want our Ball class to be an owner of the color passed in. If m_color were a std::string_view , passing in a temporary object for the color argument (e.g. a std::string returned from a function) would leave m_color dangling when the temporary color argument was destroyed.

We discuss this case in more detail (and show an example) in lesson 13.11 -- Struct miscellany .

guest

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Constructors (C++)

  • 13 contributors

To customize how a class initializes its members, or to invoke functions when an object of your class is created, define a constructor . A constructor has the same name as the class and no return value. You can define as many overloaded constructors as needed to customize initialization in various ways. Typically, constructors have public accessibility so that code outside the class definition or inheritance hierarchy can create objects of the class. But you can also declare a constructor as protected or private .

Constructors can optionally take a member initializer list. It's a more efficient way to initialize class members than assigning values in the constructor body. The following example shows a class Box with three overloaded constructors. The last two use member init lists:

When you declare an instance of a class, the compiler chooses which constructor to invoke based on the rules of overload resolution:

  • Constructors may be declared as inline , explicit , friend , or constexpr .
  • A constructor can initialize an object that has been declared as const , volatile or const volatile . The object becomes const after the constructor completes.
  • To define a constructor in an implementation file, give it a qualified name like any other member function: Box::Box(){...} .

Member initializer lists

A constructor can optionally have a member initializer list , which initializes class members before the constructor body runs. (A member initializer list isn't the same thing as an initializer list of type std::initializer_list<T> .)

Prefer member initializer lists over assigning values in the body of the constructor. A member initializer list directly initializes the members. The following example shows the member initializer list, which consists of all the identifier(argument) expressions after the colon:

The identifier must refer to a class member; it's initialized with the value of the argument. The argument can be one of the constructor parameters, a function call or a std::initializer_list<T> .

const members and members of reference type must be initialized in the member initializer list.

To ensure base classes are fully initialized before the derived constructor runs, call any parameterized base class constructors in the initializer list.

Default constructors

Default constructors typically have no parameters, but they can have parameters with default values.

Default constructors are one of the special member functions . If no constructors are declared in a class, the compiler provides an implicit inline default constructor.

If you rely on an implicit default constructor, be sure to initialize members in the class definition, as shown in the previous example. Without those initializers, the members would be uninitialized and the Volume() call would produce a garbage value. In general, it's good practice to initialize members in this way even when not relying on an implicit default constructor.

You can prevent the compiler from generating an implicit default constructor by defining it as deleted :

A compiler-generated default constructor will be defined as deleted if any class members aren't default-constructible. For example, all members of class type, and their class-type members, must have a default constructor and destructors that are accessible. All data members of reference type and all const members must have a default member initializer.

When you call a compiler-generated default constructor and try to use parentheses, a warning is issued:

This statement is an example of the "Most Vexing Parse" problem. You could interpret myclass md(); either as a function declaration or as the invocation of a default constructor. Because C++ parsers favor declarations over other things, the expression is treated as a function declaration. For more information, see Most Vexing Parse .

If any non-default constructors are declared, the compiler doesn't provide a default constructor:

If a class has no default constructor, an array of objects of that class can't be constructed by using square-bracket syntax alone. For example, given the previous code block, an array of Boxes can't be declared like this:

However, you can use a set of initializer lists to initialize an array of Box objects:

For more information, see Initializers .

Copy constructors

A copy constructor initializes an object by copying the member values from an object of the same type. If your class members are all simple types such as scalar values, the compiler-generated copy constructor is sufficient and you don't need to define your own. If your class requires more complex initialization, then you need to implement a custom copy constructor. For example, if a class member is a pointer then you need to define a copy constructor to allocate new memory and copy the values from the other's pointed-to object. The compiler-generated copy constructor simply copies the pointer, so that the new pointer still points to the other's memory location.

A copy constructor may have one of these signatures:

When you define a copy constructor, you should also define a copy assignment operator (=). For more information, see Assignment and Copy constructors and copy assignment operators .

You can prevent your object from being copied by defining the copy constructor as deleted:

Attempting to copy the object produces error C2280: attempting to reference a deleted function .

Move constructors

A move constructor is a special member function that moves ownership of an existing object's data to a new variable without copying the original data. It takes an rvalue reference as its first parameter, and any later parameters must have default values. Move constructors can significantly increase your program's efficiency when passing around large objects.

The compiler chooses a move constructor when the object is initialized by another object of the same type, if the other object is about to be destroyed and no longer needs its resources. The following example shows one case when a move constructor is selected by overload resolution. In the constructor that calls get_Box() , the returned value is an xvalue (eXpiring value). It's not assigned to any variable and is therefore about to go out of scope. To provide motivation for this example, let's give Box a large vector of strings that represent its contents. Rather than copying the vector and its strings, the move constructor "steals" it from the expiring value "box" so that the vector now belongs to the new object. The call to std::move is all that's needed because both vector and string classes implement their own move constructors.

If a class doesn't define a move constructor, the compiler generates an implicit one if there's no user-declared copy constructor, copy assignment operator, move assignment operator, or destructor. If no explicit or implicit move constructor is defined, operations that would otherwise use a move constructor use the copy constructor instead. If a class declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted.

An implicitly declared move constructor is defined as deleted if any members that are class types lack a destructor or if the compiler can't determine which constructor to use for the move operation.

For more information about how to write a non-trivial move constructor, see Move Constructors and Move Assignment Operators (C++) .

Explicitly defaulted and deleted constructors

You can explicitly default copy constructors, default constructors, move constructors, copy assignment operators, move assignment operators, and destructors. You can explicitly delete all of the special member functions.

For more information, see Explicitly Defaulted and Deleted Functions .

constexpr constructors

A constructor may be declared as constexpr if

  • it's either declared as defaulted or else it satisfies all the conditions for constexpr functions in general;
  • the class has no virtual base classes;
  • each of the parameters is a literal type ;
  • the body isn't a function try-block;
  • all non-static data members and base class subobjects are initialized;
  • if the class is (a) a union having variant members, or (b) has anonymous unions, only one of the union members is initialized;
  • every non-static data member of class type, and all base-class subobjects have a constexpr constructor

Initializer list constructors

If a constructor takes a std::initializer_list<T> as its parameter, and any other parameters have default arguments, that constructor is selected in overload resolution when the class is instantiated through direct initialization. You can use the initializer_list to initialize any member that can accept it. For example, assume the Box class (shown previously) has a std::vector<string> member m_contents . You can provide a constructor like this:

And then create Box objects like this:

Explicit constructors

If a class has a constructor with a single parameter, or if all parameters except one have a default value, the parameter type can be implicitly converted to the class type. For example, if the Box class has a constructor like this:

It's possible to initialize a Box like this:

Or pass an int to a function that takes a Box:

Such conversions can be useful in some cases, but more often they can lead to subtle but serious errors in your code. As a general rule, you should use the explicit keyword on a constructor (and user-defined operators) to prevent this kind of implicit type conversion:

When the constructor is explicit, this line causes a compiler error: ShippingOrder so(42, 10.8); . For more information, see User-Defined Type Conversions .

Order of construction

A constructor performs its work in this order:

It calls base class and member constructors in the order of declaration.

If the class is derived from virtual base classes, it initializes the object's virtual base pointers.

If the class has or inherits virtual functions, it initializes the object's virtual function pointers. Virtual function pointers point to the class's virtual function table to enable correct binding of virtual function calls to code.

It executes any code in its function body.

The following example shows the order in which base class and member constructors are called in the constructor for a derived class. First, the base constructor is called. Then, the base-class members are initialized in the order in which they appear in the class declaration. Finally, the derived constructor is called.

Here's the output:

A derived class constructor always calls a base class constructor, so that it can rely on completely constructed base classes before any extra work is done. The base class constructors are called in order of derivation—for example, if ClassA is derived from ClassB , which is derived from ClassC , the ClassC constructor is called first, then the ClassB constructor, then the ClassA constructor.

If a base class doesn't have a default constructor, you must supply the base class constructor parameters in the derived class constructor:

If a constructor throws an exception, the order of destruction is the reverse of the order of construction:

The code in the body of the constructor function is unwound.

Base class and member objects are destroyed, in the reverse order of declaration.

If the constructor is non-delegating, all fully constructed base class objects and members are destroyed. However, because the object itself isn't fully constructed, the destructor isn't run.

Derived constructors and extended aggregate initialization

If the constructor of a base class is non-public, but accessible to a derived class, then you can't use empty braces to initialize an object of the derived type under /std:c++17 mode and later in Visual Studio 2017 and later.

The following example shows C++14 conformant behavior:

In C++17, Derived is now considered an aggregate type. It means that the initialization of Base via the private default constructor happens directly, as part of the extended aggregate initialization rule. Previously, the Base private constructor was called via the Derived constructor, and it succeeded because of the friend declaration.

The following example shows C++17 behavior in Visual Studio 2017 and later in /std:c++17 mode:

Constructors for classes that have multiple inheritance

If a class is derived from multiple base classes, the base class constructors are invoked in the order in which they're listed in the declaration of the derived class:

You should expect the following output:

  • Delegating constructors

A delegating constructor calls a different constructor in the same class to do some of the work of initialization. This feature is useful when you have multiple constructors that all have to perform similar work. You can write the main logic in one constructor and invoke it from others. In the following trivial example, Box(int) delegates its work to Box(int,int,int):

The object created by the constructors is fully initialized as soon as any constructor is finished. For more information, see Delegating Constructors .

Inheriting constructors (C++11)

A derived class can inherit the constructors from a direct base class by using a using declaration as shown in the following example:

Visual Studio 2017 and later : The using statement in /std:c++17 mode and later brings into scope all constructors from the base class except ones that have an identical signature to constructors in the derived class. In general, it's best to use inheriting constructors when the derived class declares no new data members or constructors.

A class template can inherit all the constructors from a type argument if that type specifies a base class:

A deriving class can't inherit from multiple base classes if those base classes have constructors that have an identical signature.

Constructors and composite classes

Classes that contain class-type members are known as composite classes . When a class-type member of a composite class is created, the constructor is called before the class's own constructor. When a contained class lacks a default constructor, you must use an initialization list in the constructor of the composite class. In the earlier StorageBox example, if you change the type of the m_label member variable to a new Label class, you must call both the base class constructor and initialize the m_label variable in the StorageBox constructor:

In this section

  • Copy constructors and copy assignment operators
  • Move constructors and move assignment operators

Classes and structs

Was this page helpful?

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

cppreference.com

Std::list<t,allocator>:: operator=.

Replaces the contents of the container.

[ edit ] Parameters

[ edit ] return value, [ edit ] complexity, [ edit ] exceptions, [ edit ] notes.

After container move assignment (overload (2) ), unless element-wise move assignment is forced by incompatible allocators, references, pointers, and iterators (other than the end iterator) to other remain valid, but refer to elements that are now in * this . The current standard makes this guarantee via the blanket statement in [container.reqmts]/67 , and a more direct guarantee is under consideration via LWG issue 2321 .

[ edit ] Example

The following code uses operator = to assign one std::list to another:

[ edit ] See also

  • conditionally noexcept
  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • Page information
  • In other languages
  • This page was last modified on 13 November 2021, at 08:24.
  • This page has been accessed 56,380 times.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

Constructors and member initializer lists

Constructor is a special non-static member function of a class that is used to initialize objects of its class type.

In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual base subobjects and non-static data members. ( Not to be confused with std::initializer_list )

Constructors are declared using member function declarators of the following form:

Where class-name must name the current class (or current instantiation of a class template), or, when declared at namespace scope or in a friend declaration, it must be a qualified class name.

The only specifiers allowed in the decl-specifier-seq of a constructor declaration are friend , inline , explicit and constexpr (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 don't kick in until the most-derived constructor completes.

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-initializers , each of which has the following syntax

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 LiteralType . 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. Member initializer list is the place where non-default initialization of these objects can be specified. For members that cannot be default-initialized, such as members of reference and const-qualified types, member initializers must be specified. No initialization is performed for anonymous unions or variant members that do not have a member initializer.

The initializers where class-or-identifier names a virtual base class are ignored during execution of constructors of any class that is not the most derived class of the object that's being constructed.

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

Exceptions that are thrown from member initializers may be handled by function-try-block

Member functions (including virtual member functions) can be called from member initializers, but the behavior is undefined if not all direct bases are initialized at that point.

For virtual calls (if the bases are initialized), the same rules apply as the rules for the virtual calls from constructors and destructors: virtual member functions behave as if the dynamic type of * this is the class that's being constructed (dynamic dispatch does not propagate down the inheritance hierarchy) and virtual calls (but not static calls) to pure virtual member functions are undefined behavior.

Initialization order

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 the destructor wouldn't be able to ensure that the order of destruction is the reverse of the order of construction)

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

  • 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):

IMAGES

  1. Initializer List In C++

    c assignment operator initializer list

  2. C++ Initializer Lists

    c assignment operator initializer list

  3. Assignment Operators in C++

    c assignment operator initializer list

  4. C++ Initializer Lists

    c assignment operator initializer list

  5. Assignment Operators in C

    c assignment operator initializer list

  6. [100% Working Code]

    c assignment operator initializer list

VIDEO

  1. Modern C++ Programming #33: Class Basics 3

  2. Assignment Operator in C Programming

  3. Initializer List In C++

  4. Augmented assignment operators in C

  5. NPTEL Problem Solving through Programming in C ASSIGNMENT 6 ANSWERS 2024

  6. Learn JavaScript by Building a Role Playing Game

COMMENTS

  1. std::initializer_list

    An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T (that may be allocated in read-only memory). a brace-enclosed initializer list is bound to auto, including in a ranged for loop . std::initializer_list may be implemented as a pair of pointers or pointer and length.

  2. c++

    Unlike auto, where a braced-init-list is deduced as an initializer_list, template argument deduction considers it to be a non-deduced context, unless there exists a corresponding parameter of type initializer_list<T>, in which case the T can be deduced.. From §14.8.2.1/1 [temp.deduct.call] (emphasis added). Template argument deduction is done by comparing each function template parameter type ...

  3. Constructors and member initializer lists

    Constructors and member initializer lists. Constructor is a special non-static member function of a class that is used to initialize objects of its class type. In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual base subobjects and non-static data members.

  4. Initializer list

    The initializer list is the place where initialization of the object should occur, there is where the constructors for base classes and members are called. Members are initialized in the same order as they are declared, not as they appear in the initializer list. If a parameter in the constructor has the same name as one of the members, the ...

  5. 23.7

    Class assignment using std::initializer_list. You can also use std::initializer_list to assign new values to a class by overloading the assignment operator to take a std::initializer_list parameter. This works analogously to the above. We'll show an example of how to do this in the quiz solution below.

  6. When do we use Initializer List in C++?

    Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class. Example. C++.

  7. std::initializer_list reference

    A braced-init-list is used to list-initialize an object, where the corresponding constructor accepts an std::initializer_list<T> parameter; A braced-init-list is used as the right operand of assignment or as a function call argument, and the corresponding assignment operator/function accepts an std::initializer_list<T> parameter

  8. list initialization and std::initializer_list

    A std::initializer_list object is automatically constructed when: a braced-init-list is used to list-initialize an object, where the corresponding constructor accepts an std::initializer_list parameter. a braced-init-list is used as the right operand of assignment or as a function call argument, and the corresponding assignment operator ...

  9. 14.10

    This program produces the following output: Foo(6, 7) constructed Foo(6, 7) When foo is instantiated, the members in the initialization list are initialized with the specified initialization values. In this case, the member initializer list initializes m_x to the value of x (which is 6), and m_y to the value of y (which is 7).Then the body of the constructor runs.

  10. Constructors (C++)

    (A member initializer list isn't the same thing as an initializer list of type std:: ... For more information about how to write a non-trivial move constructor, see Move Constructors and Move Assignment Operators (C++). Explicitly defaulted and deleted constructors. You can explicitly default copy constructors, default constructors, ...

  11. std::list<T,Allocator>::operator=

    1) Copy assignment operator. Replaces the contents with a copy of the contents of other . If std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value is true, the allocator of *this is replaced by a copy of other. If the allocator of *this after assignment would compare unequal to its old value, the old allocator is ...

  12. Constructors and member initializer lists

    Constructor is a special non-static member function of a class that is used to initialize objects of its class type.. In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual base subobjects and non-static data members. ( Not to be confused with std::initializer_list) . Syntax. Constructors are declared using member function ...

  13. What do you prefer

    This makes it easier to find all usages of a specific constructor. All my data is POD, so i prefer designated initializers 😁. I prefer to use brace initialization. (Except I put a space before the ' {' ) whenever possible and try to reserve '=' for assignment. Assignment all the way, I hate the list init for not lists.

  14. c++

    function not viable: cannot convert argument of incomplete type 'void' to. 'live_set_item' for 1st argument. void operator=(const std::initializer_list<au_live_set_item_v1>&) {} ^. This is where I'm lost, I've tried changing the assignment operator a couple different ways looking at the cpp docs for std::initializer list.

  15. c++

    To initialize is to make ready for use. And when we're talking about a variable, that means giving the variable a first, useful value. And one way to do that is by using an assignment. So it's pretty subtle: assignment is one way to do initialization. Assignment works well for initializing e.g. an int, but it doesn't work well for initializing ...