8.3 Class Members

Classes can have these kinds of members:

Member functions. (See “Member Functions”.)

Data members.

Classes, which include classes, structures, and unions. (See “Nested Class Declarations” and “Unions”.

Enumerations. (See “Enumeration Declarations” in Chapter 6, on topic .)

Bit fields. (See “Bit Fields”.)

Friends. (See “Friends” in Chapter 10, on topic .)

Type names. (See “Type Names in Class Scope”.)

Note:

Friends are included in the preceding list because they are contained in the class declaration. However, they are not true class members, because they are not in the scope of the class.

Syntax

member-list:
member-declaration member-list
opt
access-specifier : member-listopt

member-declaration:
decl-specifiersoptmember-declarator-listopt;
function-definitionopt;
qualified-name;

member-declarator-list:
member-declarator
member-declarator-list , member-declarator

member-declarator:
declarator pure-specifieropt
identifieropt : constant-expression

pure-specifier:
= 0

The purpose of the member-list is to:

Declare the complete set of members for a given class.

Specify the access (public, private, or protected) associated with various class members.

In the declaration of a member list, you can declare members only once; redeclaration of members produces an error message. Because a member list is a complete set of the members, you cannot add members to a given class with subsequent declarations.

Class members can be divided into two general categories: member data and member functions. While it is acceptable to overload (reuse) function names within a member list, the same is not true for data member names. Data member names can be declared only once within a class.

Member declarators cannot contain initializers. Supplying an initializer produces an error message. The following code illustrates this error:

class CantInit

{

public:

long l = 7; // Error: attempt to initialize

// class member.

static int i = 9; // Error: must be defined and initialized

outside of class declaration.

};

Because a separate instance of nonstatic member data is created for each object of a given class type, the correct way to initialize member data is to use the class's constructor. (Constructors are covered in “Constructors,” in Chapter 11, on topic .) Only one shared copy of static data members exists for all objects of a given class type. Static data members must be defined and can be initialized at file scope. (For more information about static data members, see “Static Data Members”.) The following example shows how to perform these initializations:

class CanInit

{

public:

CanInit() { l = 7; } // Initializes l when new objects of type

// CanInit are created.

long l;

static int i;

static int j;

};

int CanInit::i = 15; // i is defined at file scope and

// initialized to 15. The initializer

// is evaluated in the scope of CanInit.

int CanInit::j = i; // The right side of the initializer

// is in the scope of the object being

// initialized.

Note:

The class name, CanInit, must precede i to specify that the i being defined is a member of class CanInit.