Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents
Chapter 2.  Object Lifetime


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.[1]

[1] Conceptually speaking, that is. The space that a former object occupied may be reused after its destruction without any actual release of memory. This happens in STL containers, for example.

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.


      Previous section   Next section