静态成员与常对象:类的高级控制
一、静态成员系统
1.1 静态成员变量
class BankAccount {
public:
static double totalDeposit; // 类级别存款总额
BankAccount(double amount) {
totalDeposit += amount;
}
~BankAccount() {
totalDeposit -= balance;
}
private:
double balance;
};
// 类外初始化静态成员
double BankAccount::totalDeposit = 0; // 必须初始化
1.2 静态成员函数
class SystemMonitor {
static int errorCount;
public:
static void reportError() { // 只能访问静态成员
errorCount++;
cout << "当前错误数:" << errorCount << endl;
}
void checkStatus() { /* 非静态方法 */ }
};
int SystemMonitor::errorCount = 0;
📌 静态成员特性对比表:
| 特征 | 静态成员 | 普通成员 |
|---|---|---|
| 内存分配 | 类加载时分配 | 对象实例化时分配 |
| 访问方式 | ClassName::member | object.member |
| 生命周期 | 程序运行期间 | 对象生命周期 |
| 共享性 | 所有对象共享 | 对象独享 |
二、常对象控制
2.1 const成员函数
class TemperatureSensor {
mutable int readCount; // 可被const方法修改
double currentTemp;
public:
double getTemp() const { // 承诺不修改对象状态
readCount++; // 允许修改mutable成员
return currentTemp;
}
void calibrate() { // 非const方法
currentTemp += 0.5;
}
};
const TemperatureSensor ts;
ts.getTemp(); // 允许调用
// ts.calibrate(); // 错误!常对象不能调用非const方法
2.2 mutable应用场景
class CacheSystem {
mutable string cachedData; // 缓存数据
mutable bool dirty; // 缓存标志
public:
string getData() const {
if(dirty) {
// 虽然const方法,仍可更新缓存
cachedData = fetchFromDB();
dirty = false;
}
return cachedData;
}
};
🔐 const成员函数规则:
- 不能修改普通成员变量
- 可以访问静态成员变量
- 可以调用其他const成员函数
- 可以修改mutable成员
三、单例模式实现
3.1 经典实现
class Logger {
static Logger* instance;
// 禁用拷贝和赋值
Logger(const Logger&) = delete;
Logger& operator=(const Logger&) = delete;
Logger() {} // 私有构造函数
public:
static Logger& getInstance() {
if(!instance) {
instance = new Logger();
}
return *instance;
}
void log(const string& message) {
// 日志记录实现
}
};
// 静态成员初始化
Logger* Logger::instance = nullptr;
3.2 现代C++实现(C++11起)
class ConfigManager {
public:
static ConfigManager& getInstance() {
static ConfigManager instance; // 线程安全的初始化
return instance;
}
void loadConfig(const string& path) { /*...*/ }
private:
ConfigManager() = default;
// 自动禁用拷贝和移动操作
ConfigManager(const ConfigManager&) = delete;
ConfigManager& operator=(const ConfigManager&) = delete;
};
四、综合应用案例
4.1 全局计数器系统
class GlobalCounter {
static int count;
mutable mutex mtx; // 允许const方法修改
public:
void increment() const {
lock_guard<mutex> lock(mtx);
count++;
}
int getCount() const {
lock_guard<mutex> lock(mtx);
return count;
}
static void reset() {
lock_guard<mutex> lock(mtx);
count = 0;
}
};
int GlobalCounter::count = 0;
五、重要规则与最佳实践
5.1 关键注意事项
- 静态成员初始化:必须在类外进行(除C++17的inline静态成员)
- 线程安全:静态数据需要考虑多线程访问
- 单例生命周期:需明确销毁时机,避免内存泄漏
- const正确性:正确使用const提高代码健壮性
5.2 设计原则
- 对配置类、管理器类使用单例模式
- 优先使用局部静态变量的单例实现(C++11+)
- 为所有const方法添加const修饰符
- 谨慎使用mutable,仅用于真正需要状态跟踪的成员
六、总结与提升
课后练习:
- 实现线程安全的数据库连接池(单例模式)
- 创建学生管理系统,统计总学生数(静态成员)
- 设计具有缓存功能的const方法(mutable应用)
进阶话题:
- 静态成员的模板特化
- const_cast在常对象中的使用
- 单例模式的依赖注入实现
- C++17的inline静态成员变量
性能提示:
- 频繁访问的静态成员考虑缓存到寄存器
- mutable变量应尽量小且访问快速
- 单例的懒加载/饿加载策略选择
通过合理运用静态成员和常对象控制,可以创建出高效、安全且易于维护的类结构。建议使用Valgrind等工具检测单例的内存管理,并在实际项目中结合RAII模式管理资源。记住:良好的const修饰使用可以让编译器成为你的第一道防线!