确保一个类只有一个实例,并对这个实例提供一个全局的访问节点。
方法:将类的构造函数声明为private(外部无法new),声明一个private static的类指针保存该类唯一的实例,最后提供一个public的成员函数,提供访问该实例的接口。
(1)最简单的实现(线程危险)
//懒汉式:单例类
class SINGLETON {
private:
SINGLETON(){} //构造函数私有化
static SINGLETON* p; //指向类唯一的实例
public:
static SINGLETON* instance(); //访问实例的唯一接口
};
//静态成员对象,类外初始化
SINGLETON* SINGLETON::p = nullptr;
//静态成员函数
SINGLETON* SINGLETON::instance() {
if(p == nullptr)
p = new SINGLETON(); //懒汉式:等到第一次用才去实例化对象。
return p;
}
这种实现方法不是线程安全的:例如两个线程同时调用instance方法,且p此时为nullptr,则此时会同时调用构造函数实例对象。
(2)线程安全的懒汉式(加线程锁)
//懒汉式:单例类
class SINGLETON {
private:
SINGLETON(){
pthread_mutex_init(&mutex,nullptr); //初始化线程锁
}
public:
static pthread_mutex_t mutex; //线程锁
static SINGLETON* instance(); //访问实例的唯一接口
};
//静态成员对象,类外初始化
pthread_mutex_t SINGLETON::mutex;
//静态成员函数
SINGLETON* SINGLETON::instance() {
pthread_mutex_lock(&mutex); //线程锁
static SINGLETON obj; //类唯一的实例
pthread_mutex_unlock(&mutex);
return &obj;
}
(3)线程安全的饿汉式
//饿汉式:单例类
class SINGLETON {
private:
SINGLETON(){} //构造函数私有化
static SINGLETON* p; //指向类唯一的实例
public:
static SINGLETON* instance(); //访问实例的唯一接口
};
//静态成员对象,类外初始化
SINGLETON* SINGLETON::p = new SINGLETON; //直接初始化实例
//静态成员函数
SINGLETON* SINGLETON::instance() {
return p;
}