2.1. The Object Life Cycle
There are four phases in the life of every C++ object: nonexistence, partially constructed, instantiated, and partially destroyed [Stro1997]. Furthermore, the space that an object occupies must be acquired prior to its construction, and released after its destruction.
Objects can be brought into existence in four standard ways:
Global (global, namespace, and class-static) objects exist outside the scope of any functions. They are (usually) created prior to the execution of main(), and are automatically destroyed after it (section 11.1). The memory that they occupy is allocated by the compiler/linker. Stack objects exist in a local execution frame, within a function. They are created at their point of declaration—also their point of definition—and are automatically destroyed when they go out of scope. The memory that they occupy is allocated by adjusting the stack pointer, as determined by the compiler/linker. Heap objects exist on the heap/free-store [Stro1997]. They are created by using the new operator, and are destroyed by an explicit call to the delete operator. The memory that they occupy is acquired from the free-store, which may have insufficient resources, resulting in failure to create a new object. (See section 32.2 for a more detailed discussion on what can happen, and what we can do about it.) The language infrastructure ensures that the allocation of memory and the call of the constructor are effected together, and it does the same with the call of the destructor and the release of the memory. As part of another object. In this case, the composed objects have their lifetimes tied to that of their composing object (see Chapter 5).
2.1.1 In-Place Construction
In addition to the standard ways, you can explicitly control the memory and lifetime of instances by using placement new and explicit destruction, as in:
byte_t *p = . . . // Correctly-aligned block for SomeClass
SomeClass &sc = *new(p) SomeClass(); // Create the instance
. . .
sc.SomeMethod();
. . .
sc.~SomeClass(); // Explicitly destroy the instance; p remains
Naturally, this is hacky stuff. Apart from the implementation of containers (which store by value, rather than by reference), there are few legitimate reasons to use this technique.
 |