Стандарт C++ 98 (1119566), страница 56
Текст из файла (страница 56)
] [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. ]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). ]196© ISO/IEC12 Special member functions412.6.1 Explicit initialization[Note: the order in which objects with static storage duration are initialized is described in 3.6.2 and 6.7.
]12.6.2 Initializing bases and members1ISO/IEC 14882:1998(E)[class.base.init]In the definition of a constructor for a class, initializers for direct and virtual base subobjects and nonstaticdata members can be specified by a ctor-initializer, which has the formctor-initializer:: mem-initializer-listmem-initializer-list:mem-initializermem-initializer , mem-initializer-listmem-initializer:mem-initializer-id ( expression-listopt )mem-initializer-id:::opt nested-name-specifieropt class-nameidentifier2Names in a mem-initializer-id are looked up in the scope of the constructor’s class and, if not found in thatscope, are looked up in the scope containing the constructor’s definition.
[Note: if the constructor’s classcontains a member with the same name as a direct or virtual base class of the class, a mem-initializer-idnaming the member or base class and composed of a single identifier refers to the class member. A meminitializer-id for the hidden base class may be specified using a qualified name. ] Unless the meminitializer-id names a nonstatic data member of the constructor’s class or a direct or virtual base of thatclass, the mem-initializer is ill-formed.
A mem-initializer-list can initialize a base class using any name thatdenotes 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] If a mem-initializer-id is ambiguous because it designates both a direct non-virtual baseclass and an inherited virtual 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] A ctor-initializer may initialize the member of an anonymous union that is a member ofthe constructor’s class. If a ctor-initializer specifies more than one mem-initializer for the same member,for the same base class or for multiple members of the same union (including members of anonymousunions), the ctor-initializer is ill-formed.3The expression-list in a mem-initializer is used to initialize the base class or nonstatic data member subobject denoted by the mem-initializer-id.
The semantics of a mem-initializer are as follows:— if the expression-list of the mem-initializer is omitted, the base class or member subobject is defaultinitialized (see 8.5);— otherwise, the subobject indicated by mem-initializer-id is direct-initialized using expression-list as theinitializer (see 8.5).197ISO/IEC 14882:1998(E)12.6.2 Initializing bases and members© ISO/IEC12 Special member functions[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] There is a sequence point (1.9) after the initialization of each base and member. Theexpression-list of a mem-initializer is evaluated as part of the initialization of the corresponding base ormember.4If a given nonstatic data member or base class is not named by a mem-initializer-id (including the casewhere there is no mem-initializer-list because the constructor has no ctor-initializer), then— If the entity is a nonstatic data member of (possibly cv-qualified) class type (or array thereof) or a baseclass, and the entity class is a non-POD class, the entity is default-initialized (8.5). If the entity is a nonstatic data member of a const-qualified type, the entity class shall have a user-declared default constructor.— Otherwise, the entity is not initialized.
If the entity is of const-qualified type or reference type, or of a(possibly cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member ofa const-qualified type, the program is ill-formed.After the call to a constructor for class X has completed, if a member of X is neither specified in theconstructor’s mem-initializers, nor default-initialized, nor initialized during execution of the body of theconstructor, the member has indeterminate value.5Initialization shall proceed in the following order:— First, and only for the constructor of the most derived class as described below, virtual base classes shallbe initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graphof base classes, where “left-to-right” is the order of appearance of the base class names in the derivedclass base-specifier-list.— Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list(regardless of the order of the mem-initializers).— Then, nonstatic data members shall be initialized in the order they were declared in the class definition(again regardless of the order of the mem-initializers).— Finally, the body of the constructor is executed.[Note: the declaration order is mandated to ensure that base and member subobjects are destroyed in thereverse order of initialization.
]6All sub-objects representing virtual base classes are initialized by the constructor of the most derived class(1.8). If the constructor of the most derived class does not specify a mem-initializer for a virtual base classV, then V’s default constructor is called to initialize the virtual base class subobject. If V does not have anaccessible default constructor, the initialization is ill-formed.
A mem-initializer naming a virtual base classshall be ignored during execution of the constructor of any class that is not the most derived class. [Example:198© ISO/IECISO/IEC 14882:1998(E)12 Special member functions12.6.2 Initializing bases and membersclass V {public:V();V(int);// ...};class A : public virtual V {public:A();A(int);// ...};class B : public virtual V {public:B();B(int);// ...};class C : public A, public B, private virtual V {public: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);// use V(int)// use V(int)// use V()// use V()—end example]7Names in the expression-list of a mem-initializer are evaluated in the scope of the constructor for which themem-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, initializesX::i with the value of the constructor parameter i, and initializes X::j with the value of X::i; thistakes place each time an object of class X is created. ] [Note: because the mem-initializer are evaluated inthe scope of the constructor, the this pointer can be used in the expression-list of a mem-initializer torefer to the object being initialized.
]8Member 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 adynamic_cast (5.2.7). However, if these operations are performed in a ctor-initializer (or in a function199ISO/IEC 14882:1998(E)© ISO/IEC12.6.2 Initializing bases and members12 Special member functionscalled directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes havecompleted, the result of the operation is undefined. [Example:class A {public:A(int);};class B : public A {int j;public:int f();B() : A(f()),j(f()) { }// undefined: calls member function// but base A not yet initialized// well-defined: bases are all initialized};class C {public:C(int);};class D : public B, C {int i;public:D() : C(f()),i(f()) {}// undefined: calls member function// but base C not yet initialized// well-defined: bases are all initialized};—end example]9[Note: 12.7 describes the result of virtual function calls, typeid and dynamic_casts during construction for the well-defined cases; that is, describes the polymorphic behavior of an object under construction.]12.7 Construction and destruction1[class.cdtor]For an object of non-POD class type (clause 9), before the constructor begins execution and after thedestructor finishes execution, referring to any nonstatic member or base class of the object results in undefined behavior.
[Example:structstructstructstruct200XYAB{:{:int i; };X { };int a; };public A { int j; Y y; };extern B bobj;B* pb = &bobj;int* p1 = &bobj.a;int* p2 = &bobj.y.i;// OK// undefined, refers to base class member// undefined, refers to member’s memberA* pa = &bobj;B bobj;// undefined, upcast to a base class type// definition of bobjextern X xobj;int* p3 = &xobj.i;X xobj;// OK, X is a POD class© ISO/IECISO/IEC 14882:1998(E)12 Special member functions12.7 Construction and destructionFor another example,struct W { int j; };struct X : public virtual W { };struct Y {int *p;X x;Y() : p(&x.j)// undefined, x is not yet constructed{ }};—end example]2To explicitly or implicitly convert a pointer (an lvalue) referring to an object of class X to a pointer (reference) to a direct or indirect base class B of X, the construction of X and the construction of all of its direct orindirect bases that directly or indirectly derive from B shall have started and the destruction of these classesshall not have completed, otherwise the conversion results in undefined behavior.