Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Constructors and member initializer lists

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      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
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      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

      [edit]Syntax

      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 -

      dynamic exception specification

      (until C++11)

      eitherdynamic exception specification
      ornoexcept specification

      (since C++11)
      (until C++17)

      noexcept specification

      (since C++17)
      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:

      • For classes, the identifier expression is theinjected-class-name of the immediately-enclosing class.
      • For class templates, the identifier expression isa class name that names thecurrent 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 itslookup context.

      [edit]Member initializer list

      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)
      1)Direct-initializes the data member named bymember withinitializer .member can only name non-static data members.
      2) Initializes a class object withinitializer .class can only name the following classes:
      (since C++11)
      • A direct base class or avirtual base class ofT. In this case the corresponding base class subobject is direct-initialized withinitializer .
      3) Initializes multiple base class subobjects using apack expansion.
      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=
      Run this code
      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)}

      [edit]Explanation

      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.

      [edit]Operations during construction and destruction

      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)
      • an evaluation of a member initializer list before all themember-initializer s for base classes have completed

      Delegating constructor

      If 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

      Seeusing declaration.

      (since C++11)

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

      [edit]Notes

      Feature-test macroValueStdFeature
      __cpp_delegating_constructors200604L(C++11)Delegating constructors

      [edit]Example

      Run this code
      #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);}

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      CWG 194C++98the declarator syntax of constructor only allowed
      at most one function specifier (e.g. a constructor
      cannot be declaredinlineexplicit)
      multiple function
      specifiers allowed
      CWG 257C++98it 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 263C++98the declarator syntax of constructor
      prohibited constructors from being friends
      allowed constructors
      to be friends
      CWG 1345C++98anonymous union members without default
      member initializers were default-initialized
      they are not initialized
      CWG 1435C++98the meaning of “class name” in the
      declarator syntax of constructor was unclear
      changed the syntax to a specialized
      function declarator syntax
      CWG 1696C++98reference members could be initialized to temporaries
      (whose lifetime would end at the end of constructor)
      such initialization
      is ill-formed

      [edit]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]

      [edit]See also

      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/constructor&oldid=183378"

      [8]ページ先頭

      ©2009-2025 Movatter.jp