Static Members (C++)

From RAD Studio
Jump to: navigation, search

Go Up to The Keyword this

The storage class specifier static can be used in class declarations of data and function members. Such members are called static members and have distinct properties from nonstatic members. With nonstatic members, a distinct copy exists for each instance of the class; with static members, only one copy exists, and it can be accessed without reference to any particular object in its class. If x is a static member of class X, it can be referenced as X::x (even if objects of class X have not been created yet). It is still possible to access x using the normal member access operators. For example, y.x and yptr->x, where y is an object of class X and yptr is a pointer to an object of class X, although the expressions y and yptr are not evaluated. In particular, a static member function can be called with or without the special member function syntax:

class X {
   int member_int;
public:
   static void func(int i, X* ptr);
};
void g(void)
{
   X obj;
   func(1, &obj);      // error unless there is a global func()
                       // defined elsewhere
   X::func(1, &obj);   // calls the static func() in X
                       // OK for static functions only
   obj.func(1, &obj);  // so does this (OK for static and
                       // nonstatic functions)
}

Because static member functions can be called with no particular object in mind, they do not have a this pointer, and therefore cannot access nonstatic members without explicitly specifying an object with . or ->. For example, with the declarations of the previous example, func might be defined as follows:

void X::func(int i, X* ptr)
{
   member_int = i;       // which object does member_int
                         // refer to? Error
   ptr->member_int = i;  // OK: now we know!
}

Apart from inline functions, static member functions of global classes have external linkage. Static member functions cannot be virtual functions. It is illegal to have a static and nonstatic member function with the same name and argument types.

The declaration of a static data member in its class declaration is not a definition, so a definition must be provided elsewhere to allocate storage and provide initialization.

Static members of a class declared local to some function have no linkage and cannot be initialized. Static members of a global class can be initialized like ordinary global objects, but only in file scope. Static members, nested to any level, obey the usual class member access rules, except they can be initialized.

class X {
   static int x;
   static const int size =  5;
   class inner {
      static float f;
      void func(void);     // nested declaration
      };
public :
   char array[size];
};
int X::x = 1;
float X::inner::f = 3.14;  // initialization of nested static
void X::inner::func(void) {     /*  define the nested function */  }

The principal use for static members is to keep track of data common to all objects of a class, such as the number of objects created, or the last-used resource from a pool shared by all such objects. Static members are also used to

  • Reduce the number of visible global names
  • Make obvious which static objects logically belong to which class
  • Permit access control to their names

See Also