シングルトンを作成しようとしたときに、これを思いつきました。例:(MySelf
スレッドセーフで、ダブルチェックロックを使用しないシングルトンを作成しようとしています)
class MySelf
{
private:
string Name;
int Age;
MySelf()
{
Name = "Deamonpog";
Age = 24;
cout << "Constructing MySelf : " << Name << endl;
};
friend class MySingleton;
public:
~MySelf(){ cout << "Destructing MySelf : " << Name << endl; };
int MyAge() const
{
return Age;
}
};
class MySingleton
{
private:
static MySelf mself;
public:
static MySelf * GetInstance()
{
return &mself;
}
};
MySelf MySingleton::mself;
今、私はそれを次のように簡単に使用できます、
cout << "I am " << MySingleton::GetInstance()->MyAge() << endl;
私が作成しようとしているクラスは最初から最後までそこにあるので、私は怠惰な初期化を望んでいません。しかし、このスレッドは安全ですか?(私の知る限り、それは大丈夫のようです)
これで問題がなければ、このようなジェネリックプログラミングを使用しますか?
template <class T>
class GenericSingleton
{
private:
static T _instance;
public:
static T * GetInstance()
{
return &_instance;
}
};
template <class T>
T GenericSingleton<T>::_instance;
だから私はこれを他のクラスでも使うことができます。必要なシグルトンに追加friend class GenericSingleton<MySelf>;
する必要があります(たとえば、MySelfクラスに追加する必要があります)。
この実装は問題を引き起こす可能性がありますか?私は実際にライブラリを作成しています。一部のシングルトンはエクスポートされ、一部はエクスポートされません。また、これがライブラリではなく、別のアプリケーション用である場合はどうなりますか?
- 編集 -
だから今私はこのようにする必要があります(私はまだC ++11をサポートしていないVC++を使用しているので)、
static MySelf & GetInstance()
{
WaitForMutex(mymutex); // some function from the threading library
if( NULL == _instance )
{
_instance = new MySelf();
}
ReleaseMutex(mymutex); // release function of the same library
Return _instance;
}
そして、関数を1回使用し、その後使用するためにキャッシュするようにユーザーに指示します。(または、関数の名前を変更して、Initialize()
ロックや作成なしで参照を返すための別のメソッドを作成することもできます。)では、どこにあるmymutex
べきですか?どこで初期化する必要がありますか?