### 静态类成员

如果将类成员定义为静态类成员，则允许使用类名直接访问。静态类成员是在类成员定义前使用 static 关键字标识。

例如，定义静态数据成员。

class CBook

{

public:

static unsigned int m_Price; //定义一个静态数据成员

};

在定义静态数据成员时，通常需要在类体外部对静态数据成员进行初始化。例如：

unsigned int CBook::m_Price = 10; //初始化静态数据成员

对于静态成员来说，不仅可以通过对象访问，还可以直接使用类名访问。例如：

int main(int argc, char* argv[])

{

CBook book; //定义一个 CBook 类对象 book

printf("%d\n",CBook::m_Price); //通过类名访问静态成员

printf("%d\n",book.m_Price); //通过对象访问静态成员

return 0;

}

在一个类中，静态数据成员是被所有的类对象所共享的。这就意味着无论定义多少个类对象，类的静态数据成员只有一份，同时，如果某一个对象修改了静态数据成员，其他对象的静态数据成员（实际上是同一个静态数据成员）也将改变。

例如，类对象共享静态数据成员。

int main(int argc, char* argv[])

{

CBook book,vcbook; //定义两个 CBook 对象

book.m_Price = 20; //修改静态数据成员

printf("%d\n",book.m_Price); //输出静态数据成员

printf("%d\n",vcbook.m_Price); //输出静态数据成员

return 0;

}

执行上述代码，效果如图 1 所示。

图 1 静态数据成员

由于静态数据成员 m_Price 被所有 CBook 类对象所共享，因此 book 对象修改了 m_Price 成员，它将影响到 vcbook 对象对 m_Price 成员的访问。

对于静态数据成员，还需要注意以下几点。

l 静态数据成员可以是当前类的类型，而其他数据成员只能是当前类的指针或引用类型

在定义类成员时，对于静态数据成员，其类型可以是当前类的类型，而非静态数据成员则不可以，除非数据成员的类型为当前类的指针或引用类型。

例如，静态数据成员可以是当前类的类型。

class CBook

{

public:

static unsigned int m_Price ;

CBook m_Book; //非法的定义，不允许在该类中定义所属类的对象

static CBook m_VCbook; //正确，静态数据成员允许定义类的所属类对象

CBook *m_pBook; //正确，允许定义类的所属类型的指针类型对象

};

l 静态数据成员可以作为成员函数的默认参数

在定义类的成员函数时，可以为成员函数指定默认参数，其参数的默认值也可以是类的静态数据成员，但是普通的数据成员则不能作为成员函数的默认参数。

例如，静态数据成员可以作为成员函数的默认参数。

class CBook //定义 CBook 类

{

public:

static unsigned int m_Price ; //定义一个静态数据成员

int m_Pages; //定义一个普通数据成员

void OutputInfo(int data = m_Price) //定义一个函数，以静态数据成员作为默认参数

{

printf("%d\n",data); //输出信息

}

void OutputPage(int page = m_Pages) //错误的定义，类的普通数据成员不能作为默认参数

{

printf("%d\n",page); //输出信息

}

};

在介绍完类的静态数据成员之后，下面介绍类的静态成员函数。定义类的静态成员函数与定义普通的成员函数类似，只是在成员函数前添加 static 关键字。例如：

static void OutputInfo(); //定义类的静态成员函数

类的静态成员函数只能访问类的静态数据成员，而不能访问普通的数据成员。例如：

class CBook //定义一个类 CBook

{

public:

static unsigned int m_Price ; //定义一个静态数据成员

int m_Pages; //定义一个普通的数据成员

static void OutputInfo() //定义一个静态成员函数

{

printf("%d\n",m_Price); //真确地访问

printf("%d\n",m_Pages); //非法的访问，不能访问非静态数据成员

}

};

在上述代码中，语句“printf("%d\n",m_Pages); ”是错误的，因为 m_Pages 是非静态数据成员，不能在静态成员函数中访问。

此外，对于静态成员函数不能定义为 const 成员函数，即静态成员函数末尾不能使用 const 关键字。例如，下面的静态成员函数的定义是非法的。

static void OutputInfo()const; //错误的定义，静态成员函数不能使用 const 关键字

在定义静态数据成员函数时，如果函数的实现代码处于类体之外，则在函数的实现部分不能再标识 static 关键字。例如，下面的函数定义是非法的。

static void CBook::OutputInfo() //错误的函数定义，不能使用 static 关键字

{

printf("%d\n",m_Price); //输出信息

}

上述代码如果去掉 static 关键字则是正确的。例如：

void CBook::OutputInfo() //正确的函数定义

{

printf("%d\n",m_Price); //输出信息

}