Стандарт C++ 11 (1119564), страница 77
Текст из файла (страница 77)
For another example,struct X {int i;float f;complex c;} x = { 99, 88.8, 77.7 };Here, x.i is initialized with 99, x.f is initialized with 88.8, and complex::complex(double) is called for theinitialization of x.c. — end example ] [ Note: Braces can be elided in the initializer-list for any aggregate,even if the aggregate has members of a class type with user-defined type conversions; see 8.5.1. — end note ]3[ Note: If T is a class type with no default constructor, any declaration of an object of type T (or arraythereof) is ill-formed if no initializer is explicitly specified (see 12.6 and 8.5). — end note ]§ 12.6.1270© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)4[ Note: the order in which objects with static or thread storage duration are initialized is described in 3.6.2and 6.7.
— end note ]12.6.21Initializing bases and members[class.base.init]In the definition of a constructor for a class, initializers for direct and virtual base subobjects and non-staticdata members can be specified by a ctor-initializer, which has the formctor-initializer:: mem-initializer-listmem-initializer-list:mem-initializer ...optmem-initializer , mem-initializer-list ...optmem-initializer:mem-initializer-id ( expression-listopt )mem-initializer-id braced-init-listmem-initializer-id:class-or-decltypeidentifier2In a mem-initializer-id an initial unqualified identifier is looked up in the scope of the constructor’s classand, if not found in that scope, it is looked up in the scope containing the constructor’s definition.
[ Note:If the constructor’s class contains a member with the same name as a direct or virtual base class of theclass, a mem-initializer-id naming the member or base class and composed of a single identifier refers tothe class member. A mem-initializer-id for the hidden base class may be specified using a qualified name.— end note ] Unless the mem-initializer-id names the constructor’s class, a non-static data member of theconstructor’s class, or a direct or virtual base of that class, the mem-initializer is ill-formed.3A mem-initializer-list can initialize a base class using any class-or-decltype that denotes that base class type.[ Example:struct A { A(); };typedef A global_A;struct B { };struct C: public A, public B { C(); };C::C(): global_A() { }// mem-initializer for base A— end example ]4If a mem-initializer-id is ambiguous because it designates both a direct non-virtual base class and an inheritedvirtual base class, the mem-initializer is ill-formed.
[ Example:struct A { A(); };struct B: public virtual A { };struct C: public A, public B { C(); };C::C(): A() { }// ill-formed: which A?— end example ]5A ctor-initializer may initialize a variant member of the constructor’s class. If a ctor-initializer specifies morethan one mem-initializer for the same member or for the same base class, the ctor-initializer is ill-formed.6A mem-initializer-list can delegate to another constructor of the constructor’s class using any class-ordecltype that denotes the constructor’s class itself. If a mem-initializer-id designates the constructor’s class,it shall be the only mem-initializer; the constructor is a delegating constructor, and the constructor selectedby the mem-initializer is the target constructor.
The principal constructor is the first constructor invokedin the construction of an object (that is, not a target constructor for that object’s construction). The§ 12.6.2© ISO/IEC 2011 – All rights reserved271ISO/IEC 14882:2011(E)target constructor is selected by overload resolution.
Once the target constructor returns, the body of thedelegating constructor is executed. If a constructor delegates to itself directly or indirectly, the program isill-formed; no diagnostic is required. [ Example:struct C {C( int ) { }C(): C(42) { }C( char c ) : C(42.0) { }C( double d ) : C(’a’) { }};////////#1:#2:#3:#4:non-delegating constructordelegates to #1ill-formed due to recursion with #4ill-formed due to recursion with #3— end example ]7The expression-list or braced-init-list in a mem-initializer is used to initialize the designated subobject (or,in the case of a delegating constructor, the complete class object) according to the initialization rules of 8.5for direct-initialization.[ Example:struct B1 { B1(int); /∗ ...
∗/ };struct B2 { B2(int); /∗ ... ∗/ };struct D : B1, B2 {D(int);B1 b;const int c;};D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4){ /∗ ... ∗/ }D d(10);— end example ] The initialization performed by each mem-initializer constitutes a full-expression. Anyexpression in a mem-initializer is evaluated as part of the full-expression that performs the initialization.A mem-initializer where the mem-initializer-id denotes a virtual base class is ignored during execution of aconstructor of any class that is not the most derived class.8In a non-delegating constructor, if a given non-static data member or base class is not designated by amem-initializer-id (including the case where there is no mem-initializer-list because the constructor has noctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then— if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initializedas specified in 8.5;— otherwise, if the entity is a variant member (9.5), no initialization is performed;— otherwise, the entity is default-initialized (8.5).[ Note: An abstract class (10.4) is never a most derived class, thus its constructors never initialize virtualbase classes, therefore the corresponding mem-initializers may be omitted.
— end note ] An attempt toinitialize more than one non-static data member of a union renders the program ill-formed. After the callto a constructor for class X has completed, if a member of X is neither initialized nor given a value duringexecution of the compound-statement of the body of the constructor, the member has indeterminate value.[ Example:struct A {A();};§ 12.6.2272© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)struct B {B(int);};struct C {C() { }A a;const B b;int i;int j = 5;};// initializes members as follows:// OK: calls A::A()// error: B has no default constructor// OK: i has indeterminate value// OK: j has the value 5— end example ]9If a given non-static data member has both a brace-or-equal-initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member’s brace-or-equal-initializeris ignored.
[ Example: Givenstruct A {int i = /∗ some integer expression with side effects ∗/ ;A(int arg) : i(arg) { }// ...};the A(int) constructor will simply initialize i to the value of arg, and the side effects in i’s brace-or-equalinitializer will not take place. — end example ]10In a non-delegating constructor, initialization proceeds in the following order:— First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized inthe order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes,where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.— Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list(regardless of the order of the mem-initializers).— Then, non-static data members are initialized in the order they were declared in the class definition(again regardless of the order of the mem-initializers).— Finally, the compound-statement of the constructor body is executed.[ Note: The declaration order is mandated to ensure that base and member subobjects are destroyed in thereverse order of initialization.
— end note ]11[ Example:struct V {V();V(int);};struct A : virtual V {A();A(int);};struct B : virtual V {§ 12.6.2© ISO/IEC 2011 – All rights reserved273ISO/IEC 14882:2011(E)B();B(int);};struct C : A, B, virtual V {C();C(int);};A::A(int i) : V(i) { /∗ ... ∗/ }B::B(int i) { /∗ ... ∗/ }C::C(int i) { /∗ ... ∗/ }VABCv(1);a(2);b(3);c(4);////////useuseuseuseV(int)V(int)V()V()— end example ]12Names in the expression-list or braced-init-list of a mem-initializer are evaluated in the scope of the constructor for which the mem-initializer is specified. [ Example:class X {int a;int b;int i;int j;public:const int& r;X(int i): r(a), b(i), i(i), j(this->i) { }};initializes X::r to refer to X::a, initializes X::b with the value of the constructor parameter i, initializes X::iwith the value of the constructor parameter i, and initializes X::j with the value of X::i; this takes placeeach time an object of class X is created.
— end example ] [ Note: Because the mem-initializer are evaluatedin the scope of the constructor, the this pointer can be used in the expression-list of a mem-initializer torefer to the object being initialized. — end note ]13Member functions (including virtual member functions, 10.3) can be called for an object under construction.Similarly, an object under construction can be the operand of the typeid operator (5.2.8) or of a dynamic_cast (5.2.7).
However, if these operations are performed in a ctor-initializer (or in a function called directlyor indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the resultof the operation is undefined. [ Example:class A {public:A(int);};class B : public A {int j;public:int f();B() : A(f()),// undefined: calls member function// but base A not yet initialized§ 12.6.2274© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)j(f()) { }};// well-defined: bases are all initializedclass C {public:C(int);};class D : public B, C {int i;public:D() : C(f()),// undefined: calls member function// but base C not yet initializedi(f()) { }// well-defined: bases are all initialized};— end example ]14[ Note: 12.7 describes the result of virtual function calls, typeid and dynamic_casts during construction forthe well-defined cases; that is, describes the polymorphic behavior of an object under construction.
— endnote ]15A mem-initializer followed by an ellipsis is a pack expansion (14.5.3) that initializes the base classes specifiedby a pack expansion in the base-specifier-list for the class. [ Example:template<class... Mixins>class X : public Mixins... {public:X(const Mixins&... mixins) : Mixins(mixins)... { }};— end example ]12.71Construction and destruction[class.cdtor]For an object with a non-trivial constructor, referring to any non-static member or base class of the objectbefore the constructor begins execution results in undefined behavior.