最近在项目组中听了一次关于单态(Singleton)设计模式的讲座,今天抽空整理了下, 主要记录单态(Singleton)在实现上存在的一些问题,特别是对单态(Singleton)的生命周期管理,提出了一些解决方案,值得借鉴.
1. static variable : 确保实例的唯一
private
static
MySingleton
*
m_pInstance
=
NULL;
public :
static MySingleton * GetInstance()
... {
if(m_pInstance == NULL)
return new MySingleton();
else
return m_pInstance;
}
public :
static MySingleton * GetInstance()
... {
if(m_pInstance == NULL)
return new MySingleton();
else
return m_pInstance;
}
2. private/protect Constructor:确保实例只在类中创建一次
MySingleton(){..};
3.private/protect copy contructor:
private
:
MySingleton( const MySingleton & );
MySingleton & operator = ( const MySingleton & );
MySingleton( const MySingleton & );
MySingleton & operator = ( const MySingleton & );
4. protect destructor
private: 可能有 subclass requrement?
public: 任何人都可以delete这个实例,可能会发生delete之后又在某些地方引用,所以最好不要把单态的析构暴露出来,原则是自动在Application退出时析构
5.lifetime: Kill the Singliton: when? how?
Solution1:delete it in its friend class
...其中可以考虑把这个友元类作为一个模版来实现, 写一个通用的工具类
class
Singleton
...
{
public:
static Singleton* Instance();
protected:
Singleton() ...{ }
friend class SingletonDestroyer;
virtual ~Singleton() ...{ }
private:
static Singleton* _instance;
static SingletonDestroyer _destroyer;
} ;
Singleton * Singleton::_instance = 0 ;
SingletonDestroyer Singleton::_destroyer;
Singleton * Singleton::Instance () ... {
if (!_instance) ...{
_instance = new Singleton;
_destroyer.SetSingleton(_instance);
}
return _instance;
}
class SingletonDestroyer ... {
public:
SingletonDestroyer(Singleton* = 0);
~SingletonDestroyer();
void SetSingleton(Singleton* s);
private:
Singleton* _singleton;
} ;
SingletonDestroyer::SingletonDestroyer (Singleton * s) ... {
_singleton = s;
}
SingletonDestroyer:: ~ SingletonDestroyer () ... {
delete _singleton;
}
void SingletonDestroyer::SetSingleton (Singleton * s) ... {
_singleton = s;
}
public:
static Singleton* Instance();
protected:
Singleton() ...{ }
friend class SingletonDestroyer;
virtual ~Singleton() ...{ }
private:
static Singleton* _instance;
static SingletonDestroyer _destroyer;
} ;
Singleton * Singleton::_instance = 0 ;
SingletonDestroyer Singleton::_destroyer;
Singleton * Singleton::Instance () ... {
if (!_instance) ...{
_instance = new Singleton;
_destroyer.SetSingleton(_instance);
}
return _instance;
}
class SingletonDestroyer ... {
public:
SingletonDestroyer(Singleton* = 0);
~SingletonDestroyer();
void SetSingleton(Singleton* s);
private:
Singleton* _singleton;
} ;
SingletonDestroyer::SingletonDestroyer (Singleton * s) ... {
_singleton = s;
}
SingletonDestroyer:: ~ SingletonDestroyer () ... {
delete _singleton;
}
void SingletonDestroyer::SetSingleton (Singleton * s) ... {
_singleton = s;
}
Solution2:
use static local variable instead of member variable(m_pInstance)
class
Singleton
...
{
public:
static Singleton& instance (); // return reference
void op1 ();
protected:
Singleton ();
Singleton (const Singleton&);
Singleton& operator = (const Singleton&);
} ;
...
Singleton & Singleton::instance () ... {
// created at first call; destructed after main
static Singleton instance;
// Local static object is automatically destructed after main
return instance;
}
public:
static Singleton& instance (); // return reference
void op1 ();
protected:
Singleton ();
Singleton (const Singleton&);
Singleton& operator = (const Singleton&);
} ;
...
Singleton & Singleton::instance () ... {
// created at first call; destructed after main
static Singleton instance;
// Local static object is automatically destructed after main
return instance;
}
6. multiple interacting singletons
......待续中ing