Стандарт C++ 11 (1119564), страница 24
Текст из файла (страница 24)
—end note ] The lifetime of an object of type T begins when:— storage with the proper alignment and size for type T is obtained, and— if the object has non-trivial initialization, its initialization is complete.The lifetime of an object of type T ends when:— if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or— the storage which the object occupies is reused or released.2[ Note: The lifetime of an array object starts as soon as storage with proper size and alignment is obtained,and its lifetime ends when the storage which the array occupies is reused or released.
12.6.2 describes thelifetime of base and member subobjects. — end note ]§ 3.8© ISO/IEC 2011 – All rights reserved69ISO/IEC 14882:2011(E)3The properties ascribed to objects throughout this International Standard apply for a given object onlyduring its lifetime. [ Note: In particular, before the lifetime of an object starts and after its lifetime endsthere are significant restrictions on the use of the object, as described below, in 12.6.2 and in 12.7. Also,the behavior of an object under construction and destruction might not be the same as the behavior of anobject whose lifetime has started and not ended. 12.6.2 and 12.7 describe the behavior of objects during theconstruction and destruction phases.
— end note ]4A program may end the lifetime of any object by reusing the storage which the object occupies or byexplicitly calling the destructor for an object of a class type with a non-trivial destructor. For an objectof a class type with a non-trivial destructor, the program is not required to call the destructor explicitlybefore the storage which the object occupies is reused or released; however, if there is no explicit call tothe destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not beimplicitly called and any program that depends on the side effects produced by the destructor has undefinedbehavior.5Before the lifetime of an object has started but after the storage which the object will occupy has beenallocated38 or, after the lifetime of an object has ended and before the storage which the object occupied isreused or released, any pointer that refers to the storage location where the object will be or was locatedmay be used but only in limited ways.
For an object under construction or destruction, see 12.7. Otherwise,such a pointer refers to allocated storage (3.7.4.2), and using the pointer as if the pointer were of type void*,is well-defined. Such a pointer may be dereferenced but the resulting lvalue may only be used in limitedways, as described below. The program has undefined behavior if:— the object will be or was of a class type with a non-trivial destructor and the pointer is used as theoperand of a delete-expression,— the pointer is used to access a non-static data member or call a non-static member function of theobject, or— the pointer is implicitly converted (4.10) to a pointer to a base class type, or— the pointer is used as the operand of a static_cast (5.2.9) (except when the conversion is to void*,or to void* and subsequently to char*, or unsigned char*), or— the pointer is used as the operand of a dynamic_cast (5.2.7).
[ Example:#include <cstdlib>struct B {virtual void f();void mutate();virtual ~B();};struct D1 : B { void f(); };struct D2 : B { void f(); };void B::mutate() {new (this) D2;f();... = this;}// reuses storage — ends the lifetime of *this// undefined behavior// OK, this points to valid memoryvoid g() {void* p = std::malloc(sizeof(D1) + sizeof(D2));38) For example, before the construction of a global object of non-POD class type (12.7).§ 3.870© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)B* pb = new (p) D1;pb->mutate();&pb;// OK: pb points to valid memoryvoid* q = pb;// OK: pb points to valid memorypb->f();// undefined behavior, lifetime of *pb has ended}— end example ]6Similarly, before the lifetime of an object has started but after the storage which the object will occupyhas been allocated or, after the lifetime of an object has ended and before the storage which the objectoccupied is reused or released, any glvalue that refers to the original object may be used but only in limitedways.
For an object under construction or destruction, see 12.7. Otherwise, such a glvalue refers to allocatedstorage (3.7.4.2), and using the properties of the glvalue that do not depend on its value is well-defined. Theprogram has undefined behavior if:— an lvalue-to-rvalue conversion (4.1) is applied to such a glvalue,— the glvalue is used to access a non-static data member or call a non-static member function of theobject, or— the glvalue is implicitly converted (4.10) to a reference to a base class type, or— the glvalue is used as the operand of a static_cast (5.2.9) except when the conversion is ultimatelyto cv char& or cv unsigned char&, or— the glvalue is used as the operand of a dynamic_cast (5.2.7) or as the operand of typeid.7If, after the lifetime of an object has ended and before the storage which the object occupied is reused orreleased, a new object is created at the storage location which the original object occupied, a pointer thatpointed to the original object, a reference that referred to the original object, or the name of the originalobject will automatically refer to the new object and, once the lifetime of the new object has started, canbe used to manipulate the new object, if:— the storage for the new object exactly overlays the storage location which the original object occupied,and— the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and— the type of the original object is not const-qualified, and, if a class type, does not contain any non-staticdata member whose type is const-qualified or a reference type, and— the original object was a most derived object (1.8) of type T and the new object is a most derivedobject of type T (that is, they are not base class subobjects).
[ Example:struct C {int i;void f();const C& operator=( const C& );};const C& C::operator=( const C& other) {if ( this != &other ) {this->~C();// lifetime of *this endsnew (this) C(other);// new object of type C createdf();// well-defined}return *this;§ 3.8© ISO/IEC 2011 – All rights reserved71ISO/IEC 14882:2011(E)}C c1;C c2;c1 = c2;c1.f();// well-defined// well-defined; c1 refers to a new object of type C— end example ]8If a program ends the lifetime of an object of type T with static (3.7.1), thread (3.7.2), or automatic (3.7.3)storage duration and if T has a non-trivial destructor,39 the program must ensure that an object of theoriginal type occupies that same storage location when the implicit destructor call takes place; otherwise thebehavior of the program is undefined.
This is true even if the block is exited with an exception. [ Example:class T { };struct B {~B();};void h() {B b;new (&b) T;}// undefined behavior at block exit— end example ]9Creating a new object at the storage location that a const object with static, thread, or automatic storageduration occupies or, at the storage location that such a const object used to occupy before its lifetimeended results in undefined behavior. [ Example:struct B {B();~B();};const B b;void h() {b.~B();new (const_cast<B*>(&b)) const B;}// undefined behavior— end example ]10In this section, “before” and “after” refer to the “happens before” relation (1.10).
[ Note: Therefore, undefinedbehavior results if an object that is being constructed in one thread is referenced from another thread withoutadequate synchronization. — end note ]3.91Types[basic.types][ Note: 3.9 and the subclauses thereof impose requirements on implementations regarding the representationof types. There are two kinds of types: fundamental types and compound types.
Types describe objects(1.8), references (8.3.2), or functions (8.3.5). — end note ]39) That is, an object for which a destructor will be called implicitly—upon exit from the block for an object with automaticstorage duration, upon exit from the thread for an object with thread storage duration, or upon exit from the program for anobject with static storage duration.§ 3.972© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)2For any object (other than a base-class subobject) of trivially copyable type T, whether or not the objectholds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an arrayof char or unsigned char.40 If the content of the array of char or unsigned char is copied back into theobject, the object shall subsequently hold its original value.