定义
保证该类只有一个实例(static私有变量),并提供一个访问的它的全部访问点(getInstance()
方法),该单例可以被所有程序模块共享.
特点
1)此类不可被复制.
2)此类不可被公开构造.
也就是说,在c++中,它的构造函数,拷贝构造函数,赋值函数不能被公开调用.
实现方式
懒汉式
个人理解,“懒汉式”,那一定很懒,而在它的实现过程中也是一样,是只有用到时,才会被构造.
也就是在第一次用到类实例的时候才会被实例化.
懒汉式的实现方式
a. 静态指针+用到时初始化(最常用)
b. 局部静态变量
- 实现一:静态指针+用到时初始化(懒汉式,推荐这种写法,并启用c++11,这种写法就没问题的)
class Singleton{
private:
static Singleton * instance;
Singleton(){}
Singleton(const Singleton& tmp){}
Singleton& operator=(const Singleton& tmp){}
public:
static Singleton* getInstance(){
if(instance == NULL){
instance = new Singleton();
}
return instance;
}
};
Singleton* Singleton::instance = NULL;
C++11标准之后,static就是线程安全的,所以C++11单例模式就可以不用加锁了,直接static是没问题的,就如上面所示。
但是c++98标准的static是非线程安全的,还是需要加锁的。
我记得在共享单车的项目(使用的是c++14)中直接就是按照上面这么写的,没有加锁
如果你采用的是c++98的标准,则要加锁,按照下面这么写:
class Singleton{
private:
static pthread_mutex_t mutex;//互斥锁
static Singleton * instence;
Singleton(){
pthread_mutex_init(&mutex, NULL);
}
Singleton(const Singleton& tmp){}
Singleton& operator=(const Singleton& tmp){}
public:
static Singleton* getInstence(){
pthread_mutex_lock(&mutex);//加锁
if(instence == NULL){
instence = new Singleton();
}
pthread_mutex_unlock(&mutex);//解锁,其他的不变
return instence;
}
};
Singleton* Singleton::instence = NULL;
pthread_mutex_t Singleton::mutex;
/*
但是加锁后,有点小问题:
每次判断实例对象是否为空,都要被锁定,如果是多线程的话,就会造成大量线程阻塞。
不过你要是并发量不大,没啥问题
*/
- 实现二:局部静态变量
class Singleton{
private:
Singleton(){
//pthread_mutex_init(&mutex, NULL);
}
Singleton(const Singleton& temp){}
Singleton& operator=(const Singleton& temp){}
public:
static Singleton* getInstence(){
static Singleton instence;
return &instence;
}
};
饿汉式
“饿汉式”,那一定很饿,它不会等到用到时才初始化,它是直接进行初始化.文章来源:https://www.toymoban.com/news/detail-531776.html
饿汉式的实现模式
a. 直接定义静态对象
b. 静态指针+类外初始化时new空间文章来源地址https://www.toymoban.com/news/detail-531776.html
- 实现一:直接定义静态对象
//在.h文件中
class Singleton
{
public:
//get函数公有
static Singleton& GetInstance();
private:
Singleton(){}//构造私有
//拷贝构造与赋值函数只用声明,不用实现
Singleton(const Singleton&);//拷贝私有
Singleton& operator=(const Singleton&);//赋值私有
private:
static Singleton m_Instance;//单例
};
//在.cpp文件中
Singleton Singleton::m_Instance;//类外定义,全局定义
Singleton& Singleton::GetInstance()
{
return m_Instance;
}
//在.cpp文件中调用
Singleton& instance = Singleton::GetInstance();
- 实现二:静态指针+类外初始化时new空间(饿汉式,推荐这种写法)
饿汉模式本身就是线程安全的不用加锁。所以不用纠结
class Singleton{
private:
static Singleton* instence;
Singleton(const Singleton& temp){}
Singleton& operator=(const Singleton& temp){}
protected:
Singleton(){}
public:
static Singleton* getInstence(){
return instence;
}
};
Singleton* Singleton::instence = new Singleton();
到了这里,关于设计模式_单例模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!