class Restaurant {
public:
static Restaurant* getInstance() {
if (!instance) instance = new Restaurant(100);
return instance;
}
int getSize() { return size; }
void setSize(int s) { size = s; }
private:
Restaurant(int s) : size(s) {}
int size;
static Restaurant* instance;
};
Restaurant* Restaurant::instance = nullptr;
C++11 保證靜態局部變量初始化線程安全,且自動析構:
class Restaurant {
public:
static Restaurant& getInstance() {
static Restaurant instance(100); // 魔法靜態
return instance;
}
int getSize() { return size; }
void setSize(int s) { size = s; }
private:
Restaurant(int s) : size(s) {}
Restaurant(const Restaurant&) = delete;
Restaurant& operator=(const Restaurant&) = delete;
int size;
};
static Restaurant* instance = nullptr;
static mutex mtx;
static Restaurant* getInstance() {
if (!instance) {
lock_guard lock(mtx);
if (!instance) instance = new Restaurant(100);
}
return instance;
}
| 版本 | 線程安全 | 優點 | 缺點 |
|---|---|---|---|
| 懶漢式 | 否 | 簡單 | 多線程下可能創建多實例 |
| C++11 靜態局部 | 是 | 標準保證、自動析構、無鎖 | 需 C++11 支持 |
| DCLP | 是 | 兼容舊標準 | 代碼繁瑣、易寫錯 |
| 饿汉式 | 是 | 極簡單 | 程序啟動即構造、可能浪費資源 |
**首選 C++11 靜態局部變量寫法**:代碼最少、標準保證線程安全、自動管理生命周期、禁止拷貝/移動。
若需延遲初始化且不依賴 C++11,使用 std::call_once 或 DCLP(配合 atomic 和內存序)。
C++ Singleton 核心在於:私有構造、靜態獲取方法、禁止拷貝。現代 C++ 推薦 static T& getInstance() { static T instance; return instance; } 一行解決所有問題。