设计模式(2)单例模式
设计模式(2)单例模式
解决什么问题?
一个很典型的例子,windows系统中的任务管理器。这是一个具有唯一性的软件,我们不希望有两个不一样的任务管理器出现在我们的操作系统中。像这样的,有且只有一个的对象的类,我们用单例模式。
如何解决
单例模式:
- 私有化构造方法
- 在类的内部创建一个对象
- 通过公开的方法,返回这个对象
(1)有缺陷的懒汉式
class Singleton{
public:
static Singleton* getInstance();
~Singleton(){}
private:
Singleton(){}
Singleton(const Singleton& obj) = delete;
Singleton& operator=(const Singleton& obj) = delete;
static Singleton* m_pSingleton;
};
Singleton* Singleton::m_pSingleton = NULL;
Singleton* Singleton::getInstance(){
if(m_pSingleton == NULL)m_pSingleton = new Singleton;
return m_pSingleton;
}
这里有两个很明显的缺点:
- 线程不安全。如果同时有两个线程创建线程,他们都会判断instance没有被创建,这个时候就会创建两个instance。这个时候就要考虑加锁。
- 内存泄漏。我们只有new对象,但是没有delete对象,所以需要考虑智能指针。
(2)优化的懒汉式
mutex mt;
class Singleton{
private:
Singleton(){}
Singleton(const Singleton& obj) = delete;
Singleton& operator=(const Singleton& obj) = delete;
public:
static Singleton* m_pSingleton;
static shared_ptr<Singleton> getInstance();
~Singleton(){}
};
shared_ptr<Singleton> Singleton::m_pSingleton = NULL;
shared_ptr<Singleton> Singleton::getInstance(){
if(m_pSingleton == NULL){
mt.lock();
if(m_pSingleton == NULL)
m_pSingleton = shared_ptr<Singleton>(new Singleton());
mt.unlock();
}
return m_pSingleton;
}
(3)Meyers' Singleton
一种很神奇的写法
class Singleton{
private:
Singleton(){}
public:
Singleton(const Singleton& obj) = delete;
Singleton& operator=(const Singleton& obj) = delete;
//static Singleton* m_pSingleton;
static Singleton& getInstance();
~Singleton(){}
};
//shared_ptr<Singleton> Singleton::m_pSingleton = NULL;
static Singleton& Singleton::getInstance(){
static Singleton instance;
return instance;
}
(4)饿汉式
class Singleton{
private:
Singleton(){}
static Singleton instance;
public:
Singleton(const Singleton& obj) = delete;
Singleton& operator=(const Singleton& obj) = delete;
// static Singleton* m_pSingleton;
static Singleton& getInstance();
~Singleton(){}
};
//shared_ptr<Singleton> Singleton::m_pSingleton = NULL;
static Singleton& Singleton::getInstance(){
return instance;
}
Singleton* Singleton::instance = new Singleton();