Member functions are either static or nonstatic. The behavior of static member functions differs from that of other member functions because static member functions have no implicit this argument. Member functions, whether static or nonstatic, can be defined either in the class declaration or outside the class declaration.
If a member function is defined inside a class declaration, it is treated as an inline function, and there is no need to qualify the function name with its class name. Although functions defined inside class declarations are already treated as inline functions, you can use the inline keyword to document code. (For more information, see “Inline Member Functions”.)
An example of declaring a function within a class declaration follows:
class Account
{
public:
// Declare the member function Deposit within the declaration
// of class Account.
double Deposit( double HowMuch )
{
balance += HowMuch;
return balance;
}
private:
double balance;
};
If a member function's definition is outside the class declaration, it is treated as an inline function only if it is explicitly declared as inline. In addition, the function name in the definition must be qualified with its class name using the scope-resolution operator (::).
The following example is identical to the previous declaration of class Account, except the Deposit function is defined outside the class declaration:
class Account
{
public:
// Declare the member function Deposit but do not define it.
double Deposit( double HowMuch );
private:
double balance;
};
inline double Account::Deposit( double HowMuch )
{
balance += HowMuch;
return balance;
}
Note:
While member functions can be defined either inside a class declaration or separately, no member functions can be added to a class after the class is defined.
Classes containing member functions can have many declarations, but the member functions themselves must have only one definition in a program. Multiple definitions cause an error message at link time. If a class contains inline function definitions, the function definitions must be identical to observe this “one definition” rule.
Nonstatic member functions have an implied argument, this, that points to the object through which the function is invoked. The type of this is type * const. These functions are considered to have class scope and can use class data and other member functions in the same class scope directly. In the preceding example, the expression balance += HowMuch adds the value of HowMuch to the class member balance. Consider the following statements:
Account Checking;
Checking.Deposit( 57.00 );
The preceding code declares an object of type Account, then invokes the member function Deposit to add $57.00 to it. In the function Account::Deposit, balance is taken to mean Checking.balance (the balance member for this object).
Nonstatic member functions are intended to operate on objects of their class type. Calling such a function on objects of different types (using explicit type conversions) causes undefined behavior.
Static member functions are considered to have class scope. In contrast to nonstatic member functions, these functions have no implicit this argument; therefore, they can use only static data members, enumerators, or nested types directly. Static member functions can be accessed without using an object of the corresponding class type. Consider this example:
class WindowManager
{
public:
static int CountOf(); // Return count of open windows.
void Minimize(); // Minimize current window.
WindowManager SideEffects(); // Function with side effects.
...
private:
static int wmWindowCount;
};
int WindowManager::wmWindowCount = 0;
...
// Minimize (show iconic) all windows
for( int i = 0; i < WindowManager::CountOf(); ++i )
rgwmWin[i].Minimize();
In the preceding code, the class WindowManager contains the static member function CountOf. This function returns the number of windows open but is not necessarily associated with a given object of type WindowManager. This concept is demonstrated in the loop where the CountOf function is used in the controlling expression; because CountOf is a static member function, it can be called without reference to an object.
Static member functions have external linkage. These functions do not have this pointers (covered in the next section). As a result, the following restrictions apply to such functions:
They cannot access nonstatic class member data using the member-selection operators (. or –>).
They cannot be declared as virtual.
They cannot have the same name as a nonstatic function that has the same argument types.
Note:
The left side of a member-selection operator (. or –>) that selects a static member function is not evaluated. This can be important if the function is used for its side effects. For example, the expression SideEffects().CountOf() does not call the function SideEffects.