An object of a derived class is made up of a component that represents each base class and a component that is unique to the particular class. Objects of classes that have member objects also contain components of other class types. This section describes how these component objects are initialized when an object of the class type is created.
To perform the initialization, the constructor-initializer, or ctor-initializer, syntax is used.
ctor-initializer:
mem-initializer-list
mem-initializer-list:
mem-initializer
mem-initializer,mem-initializer-list
mem-initializer:
complete-class-name(expression-listopt)
identifier(expression-listopt)
This syntax, used in constructors, is described more fully in the next section, “Initializing Member Objects” and “Initializing Base Classes”.
Classes can contain member objects of class type, but to ensure that initialization requirements for the member objects are met, one of the following conditions must be met:
The contained object's class requires no constructor.
The contained object's class has an accessible default constructor.
The containing class's constructors all explicitly initialize the contained object.
The following example shows how to perform such an initialization:
// Declare a class Point.
class Point
{
public:
Point( int x, int y ) { _x = x; _y = y; }
private:
int _x, _y;
};
// Declare a rectangle class that contains objects of type Point.
class Rect
{
public:
Rect( int x1, int y1, int x2, int y2 );
private:
Point _topleft, _bottomright;
};
// Define the constructor for class Rect. This constructor
// explicitly initializes the objects of type Point.
Rect::Rect( int x1, int y1, int x2, int y2 ) :
_topleft( x1, y1 ), _bottomright( x2, y2 )
{
}
The Rect class, shown in the preceding example, contains two member objects of class Point. Its constructor explicitly initializes the objects _topleft and _bottomright. Note that a colon follows the closing parenthesis of the constructor (in the definition). The colon is followed by the member names and arguments with which to initialize the objects of type Point.
Warning:
The order in which the member initializers are specified in the constructor does not affect the order in which the members are constructed; the members are constructed in the order they are declared in the class.
Reference and const member objects must be initialized using the member initialization syntax shown in “Syntax” in “Initializing Bases and Members”. There is no other way to initialize these objects.
Direct base classes are initialized in much the same way as member objects. Consider the following example:
// Declare class Window.
class Window
{
public:
Window( Rect rSize );
...
};
// Declare class DialogBox, derived from class Window.
class DialogBox : public Window
{
public:
DialogBox( Rect rSize );
...
};
// Define the constructor for DialogBox. This constructor
// explicitly initializes the Window subobject.
DialogBox::DialogBox( Rect rSize ) : Window( rSize )
{
}
Note that in the constructor for DialogBox, the Window base class is initialized using the argument rSize. This initialization consists of the name of the base class to initialize, followed by a parenthesized list of arguments to the class's constructor.
In initialization of base classes, the object that is not the subobject representing a base class's component is considered a “complete object.” The complete object's class is considered the “most derived” class for the object.
The subobjects representing virtual base classes are initialized by the constructor for the most derived class. That means that where virtual derivation is specified, the most derived class must explicitly initialize the virtual base class, or the virtual base class must have a default constructor. Initializations for virtual base classes that appear in constructors for classes other than the most derived class are ignored.
Although initialization of base classes is usually restricted to direct base classes, in Microsoft C++, a class constructor can initialize an indirect virtual base class.¨
Initialization Order of Bases and Members
Base classes and member objects are initialized in the following order:
1.Virtual base classes are initialized in the order in which they appear in the directed acyclic graph. For information about using the directed acyclic graph to construct a list of unique subobjects, see “Virtual Base Classes” in Chapter 9. (Note that these subobjects are destroyed by walking the same list in reverse.) For more information about how the directed acyclic graph is traversed, see “Order of Destruction”.
2.Nonvirtual base classes are initialized in the order in which they are declared in the class declaration.
3.Member objects are initialized in the order in which the objects are declared in the class.
The order in which base classes and member objects are initialized is not affected by the order in which the member initializers or base-class initializers appear in the member-initializer-list of the constructor.
Initializers for base classes and member objects are evaluated in the scope of the constructor with which they are declared. Therefore, they can refer implicitly to class-member data.