避免使用有开销的Magic Static¶
方式一:显式初始化,主线程启动时初始化,优先使用
使用场景: 适用于对初始化顺序有严格要求、需要完全控制生命周期、追求极致访问性能的严苛场景。
#include <iostream>
// 单例类
class TradingConfig {
public:
inline int getMaxOrderSize() const { return max_order_size; }
private:
friend void InitializeSingletons(); // 允许初始化函数访问私有构造
TradingConfig() : max_order_size(0) {}
int max_order_size;
};
// 全局指针
static TradingConfig* g_config_instance = nullptr;
// 访问函数
inline TradingConfig& GetConfig() { return *g_config_instance; }
// 初始化函数
void InitializeSingletons() {
// 使用 placement new 在静态内存上构造,避免堆分配
static alignas(TradingConfig) char buffer[sizeof(TradingConfig)];
g_config_instance = new (buffer) TradingConfig();
}
int main() {
// 1. 在进入热路径前,手动调用初始化
InitializeSingletons();
// 2. 在热路径中零开销访问
int size = GetConfig().getMaxOrderSize();
std::cout << "Max order size: " << size << std::endl;
return 0;
}
方式二:全局实例(饿汉式),C++运行时保证
使用场景: 适用于单例之间无依赖关系、或依赖关系简单、且希望代码最简洁的场景。
#include <iostream>
// 单例类
class Logger {
public:
void log(const char* message) {
std::cout << "[LOG] " << message << std::endl;
}
};
// 在 main 执行前,由C++运行时自动初始化
static Logger g_logger_instance;
// 访问函数
inline Logger& GetLogger() { return g_logger_instance; }
int main() {
// 直接使用,零开销访问
GetLogger().log("Application started.");
return 0;
}