跳转至

避免使用有开销的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;
}