I came up with this while trying to create a singleton.
Example: ( I am trying to make MySelf
a singleton which is thread safe and without using double checked locking )
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;
Now i can easily use it like,
cout << "I am " << MySingleton::GetInstance()->MyAge() << endl;
I dont want lazy initialization because the class i am gonna create is going to be there from the start to end. But is this thread safe? ( to my knowledge it seems ok )
If this is ok, then shall i use generic programming like this,
template <class T>
class GenericSingleton
{
private:
static T _instance;
public:
static T * GetInstance()
{
return &_instance;
}
};
template <class T>
T GenericSingleton<T>::_instance;
So i can use this with any other class too. and i just have to add friend class GenericSingleton<MySelf>;
to the needed sigleton ( e.g. to MySelf class ).
Could this implementation cause trouble? I am actually creating a library. Some singletons are to be exported and some are not. Also what if this is for not a library but just another application?
-- EDIT --
So now i have to do it like this (since i am using VC++ which still doesn't support C++11 ) ,
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;
}
And tell the user to use the function once and cache it for usage after that.
( Or i can also rename the function to Initialize()
and make another method for just returning the reference without any lock or creation. )
So where does the mymutex
should be? and where should it be initialized?