面试题2:实现singleton模式
1 实现singleton模式
题目:设计一个类,我们只能生成该类的一个实例
2 解法一
思路:
1.将构造函数设置为私有函数禁止直接创造实例。
2.定义静态实例,在需要的时候创建
class Singleton
{
private:
singleton(){};//对外禁用构造函数
singleton(const singleton&){};//对外禁用拷贝构造函数
singleton& operator=(const singleton&){};//对外禁用=赋值符号
static singleton* m_instance;
public:
static Singleton* GetInstance();
};
static Singleton* Singleton::GetInstance()
{
if( m_instance == NULL)
{
m_instance = new Singleton();
}
return m_instance;
}
//注意类的static成员需要在类外初始化
Singleton* Singleton::m_instance = NULL;
方法一中的代码,在单线程中可以很好的工作,但在多线程情况下会出问题。因为多个线程同时调用GetInstance()方法,可能导致有产生多个实例。
2 解法二
思路:在原有基础上加同步锁,保证多线程安全
class Singleton
{
private:
singleton(){};//对外禁用构造函数
singleton(const singleton&){};//对外禁用拷贝构造函数
singleton& operator=(const singleton&){};//对外禁用=赋值符号
static singleton* m_instance;
static pthread_mutex_t mutex;
public:
static Singleton* GetInstance();
};
static Singleton* Singleton::GetInstance()
{
pthread_mutex_lock(&mutex);
if( m_instance == NULL)
{
m_instance = new Singleton();
}
pthread_mutex_unlock(&mutex);
return m_instance;
}
//注意类的static成员需要在类外初始化
Singleton* Singleton::m_instance = NULL;
pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
我们每次通过属性m_instance得到Singleton的实例,都会试图加上一个同步锁,而加锁的过程是非常耗时的操作,应尽量避免
3 解法三
思路:我们只在实例没创建之前需要加锁操作,当实例创建出来后,我们不需要执行加锁操作了。但为了避免在还没实例还没初始化完,另一个线程就调用,造成不可预料的后果,定义局部变量ptmp过渡。
class Singleton
{
private:
singleton(){};//对外禁用构造函数
singleton(const singleton&){};//对外禁用拷贝构造函数
singleton& operator=(const singleton&){};//对外禁用=赋值符号
static singleton* m_instance;
static pthread_mutex_t mutex;
public:
static Singleton* GetInstance();
};
static Singleton* Singleton::GetInstance()
{
if( m_instance == NULL)
{
pthread_mutex_lock(&mutex);
if( m_instance == NULL)
{
Singleton* ptmp = new Singleton();
m_instance = ptmp;
}
pthread_mutex_unlock(&mutex);
}
return m_instance;
}
//注意类的static成员需要在类外初始化
Singleton* Singleton::m_instance = NULL;
pthread_mutex_t Singleton::mutex = PTHREAD_MUTEX_INITIALIZER;
4 解法四
思路:未使用之前,直接实例化。这种模式,在多线程环境下肯定是线程安全的,因为不存在多线程实例化的问题。
class Singleton
{
private:
singleton(){};//对外禁用构造函数
singleton(const singleton&){};//对外禁用拷贝构造函数
singleton& operator=(const singleton&){};//对外禁用=赋值符号
static singleton* m_instance;
public:
static Singleton* GetInstance();
};
static Singleton* Singleton::GetInstance()
{
return m_instance;
}
//注意类的static成员需要在类外初始化
Singleton* Singleton::m_instance = new Singleton();
参考:
https://blog.csdn.net/qq_33369979/article/details/108678276
https://www.cnblogs.com/myd620/p/6133420.html

浙公网安备 33010602011771号