一、概述
在 C++ 中,静态成员(包括静态数据成员和静态成员函数)是属于类本身的成员,而不是类的某个对象的成员。它们在所有对象之间共享,即所有对象都共享同一份静态数据成员和静态成员函数。静态成员在类的所有实例中只有一份,而不是每个实例各有一份。
二、静态数据成员
格式
static 数据类型 数据成员名; //定义静态数据成员
数据类型 类名::静态数据成员名=初始值; //初始化
类名::静态数据成员名; //用类名访问静态数据成员
对象名.静态数据成员名; //用对象访问静态数据成员
对象指针->静态数据成员名;//用对象访问静态数据成员
特点
- 共享性:静态数据成员在类的所有对象之间共享,所有对象访问的都是同一个静态数据成员。
- 类级别的存储:静态数据成员在程序开始时分配内存,程序结束时释放。
- 必须在类外部定义:静态数据成员必须在类外进行定义和初始化。
#include <iostream>
class MyClass {
public:
static int count; // 声明静态数据成员
MyClass() {
count++;
}
static void printCount() { // 静态成员函数
std::cout << "Count: " << count << std::endl;
}
};
// 在类外定义并初始化静态数据成员
int MyClass::count = 0;
int main() {
MyClass obj1;
MyClass obj2;
MyClass obj3;
// 通过对象或类名访问静态数据成员
std::cout << "Count (via obj1): " << obj1.count << std::endl;
std::cout << "Count (via MyClass): " << MyClass::count << std::endl;
// 调用静态成员函数
MyClass::printCount();
return 0;
}
三、静态成员函数
格式
1.声明静态成员函数:在类的定义中使用 static
关键字声明静态成员函数。
class MyClass {
public:
static void printCount();
};
2.定义静态成员函数:在类的定义外部定义静态成员函数。注意要使用类名进行限定。
void MyClass::printCount() {
std::cout << "Count: " << count << std::endl;
}
3.调用静态成员函数:可以使用类名调用静态成员函数。
MyClass::printCount();
也可以通过对象调用静态成员函数,但不推荐这样做,因为静态成员函数不依赖于具体对象。
obj1.printCount();
特点
- 只能访问静态成员:静态成员函数只能访问静态数据成员和其他静态成员函数,不能访问非静态数据成员和非静态成员函数。
class MyClass {
private:
int nonStaticMember;
public:
static void staticFunction() {
// 非法:不能访问非静态成员
// std::cout << nonStaticMember << std::endl;
// 合法:可以访问静态成员
std::cout << count << std::endl;
}
static int count; // 静态数据成员
};
-
调用方式:静态成员函数可以通过类名直接调用,也可以通过对象调用。但推荐通过类名调用,以明确其静态性质。
示例
#include <iostream>
class MyClass {
public:
static int count; // 静态数据成员
static void printCount() { // 静态成员函数
std::cout << "Count: " << count << std::endl;
}
};
// 在类外定义并初始化静态数据成员
int MyClass::count = 0;
int main() {
MyClass::printCount(); // 通过类名调用静态成员函数
MyClass obj1;
obj1.printCount(); // 通过对象调用静态成员函数
return 0;
}
四、总结
- 静态数据成员:在类的所有实例之间共享,必须在类外定义和初始化。
- 静态成员函数:可以直接通过类名调用,只能访问静态成员。
使用静态成员,可以方便地在类的所有实例之间共享数据或函数,并且可以在不创建对象的情况下调用类的成员函数。