「Scott Meyers によるダブル チェック ロックの危険性」に関する論文を読んでいました。http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
著者は、ダブル チェック ロックが失敗する理由を示しています (ページ 3、セクション 4)。C++11 を使わずにこの問題を回避する方法を考えていました。C++ 11 を使用したくないというわけではありませんが、std::call_once などの関数を使用せずに解決できるかどうかを確認するだけです。
class Singleton {
public:
static Singleton* instance();
private:
static Singleton* pInstance;
int someData_;
};
Singleton* Singleton::instance()
{
class SeqAssign{
public:
SeqAssign(Singleton*& pInst, Singleton* pNew):
pInstance(pInst), pNewedInst(pNew){
}
~SeqAssign(){
pInstance = pNewedInst;
}
private:
Singleton*& pInstance;
Singleton* pNewedInst;
};
if (pInstance == 0) { // 1st test
Lock lock;
if (pInstance == 0) { // 2nd test
SeqAssign seq(pInstance, new Singleton);
}
}
return pInstance;
}
Singleton::instance() のコードはマルチスレッド環境で動作しますか? SeqAssign クラスのコンストラクターとデストラクタが呼び出される順序は決定論的です。