更多 C++ 慣用法/首次使用時構造
外觀
確保在物件第一次使用之前對其進行初始化。具體來說,確保非區域性靜態物件在其第一次使用之前被初始化。
延遲構造/求值
具有非平凡建構函式的靜態物件必須在使用之前初始化。如果未採取適當的措施,則可能會在非區域性靜態物件初始化之前訪問它。
struct Bar {
Bar () {
cout << "Bar::Bar()\n";
}
void f () {
cout << "Bar::f()\n";
}
};
struct Foo {
Foo () {
bar_.f ();
}
static Bar bar_;
};
Foo foo;
Bar Foo::bar_;
int main () {}
在上面的程式碼中,Bar::f() 在其建構函式被呼叫之前被呼叫。應該避免這種情況。
有兩種可能的解決方案,取決於所考慮物件的解構函式是否具有非平凡的析構語義。將原本是靜態的物件封裝在一個函式中,以便該函式在使用之前對其進行初始化。
- 使用動態分配在首次使用時構造
struct Foo {
Foo () {
bar().f ();
}
Bar & bar () {
static Bar *b = new Bar ();
return *b;
}
};
如果物件具有具有非平凡語義的解構函式,則使用區域性靜態物件代替動態分配,如下所示。
- 使用區域性靜態在首次使用時構造
struct Foo {
Foo () {
bar().f ();
}
Bar & bar () {
static Bar b;
return b;
}
};
- 單例模式的實現通常使用這種慣用法。
- 自適應通訊環境 (ACE) 中的 ACE_TSS<T> 類模板用於線上程特定儲存 (TSS) 中建立和訪問物件,它使用這種慣用法。