函數內 static T obj; 首次調用時初始化。多線程並發首次調用可能導致重複構造,造成資源洩漏或邏輯錯誤。
class Base {
public:
Base() { ptr = new int[100]; }
~Base() { delete[] ptr; }
int* ptr;
};
void foo() { static Base b; } // 多線程調用
// 可能構造兩次,第二次構造覆蓋 ptr,第一次內存洩漏
// 析構時雙重 delete → 崩潰
標準保證 static 區域變量初始化線程安全 (雙重檢查鎖模式)。直接使用即可。
// 方案 1:全局/類靜態成員 + pthread_once / CallOnce
Base& getInstance() {
static Base* instance = nullptr;
static pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once(&once, []{ instance = new Base(); });
return *instance;
}
// 方案 2:互斥鎖雙重檢查 (需 volatile/atomic 修飾 guard)
Base& getInstance() {
static Base* instance = nullptr;
static mutex mtx;
if (!instance) {
lock_guard<mutex> lock(mtx);
if (!instance) instance = new Base();
}
return *instance;
}
-std=c++11 / /std:c++14)std::call_once 或 C++11 魔法靜態