感觉自己最近一直重拾校招时候的知识。不过现在看很多问题比校招时候更容易理解,并且能够学会运用。只求自己抓紧时间,能够抓住每次来之不易的机会吧。
今天,写一个线程安全的C++单例模式。
1.所谓单例模式,就是让该类只实例化一个对象。
优点:
①减少内存,减少资源的多重占用。
②该类实例化一个对象,减少系统开销。
缺点:
①没有接口,扩展难。
②和单一职责原则冲突。(一个类的定义就是定义了一套逻辑,不在意实例化了几个对象)
2.代码实现单例
懒汉式单例模式
(懒汉,只有在饿的时候才去蒸馒头)
#include<iostream>
using namespace std;
//定义一个用于线程安全的锁。
std::mutex singleMutex;
class Single()
{
public:
//GetInstance方法必须为静态方法,静态方法只可调用静态成员和静态函数并且不能用virtual和const修饰
static Single* GetInstance()
{
//注意加锁的位置,当程序一进入get方法立马锁住,在if中再上锁的话也不是线程安全
singleMutex.lock();
if(Single::m_single == nullptr)
{
m_single = new Single();
}
singleMutex.unlock(); //解锁
return m_single; //返回获取到的实例,当不同的对象调用get方法时,静态的get方法直接调用静态成员m_single。
}
private:
//多读书还是有好处,Effective C++中有一条:
//程序要干什么一定要声明,比如你不让它拷贝,你就要想办法不让它有默认的拷贝构造和赋值操作符方法。
//而把默认拷贝函数和赋值函数屏蔽的一个方法就是显示私有的声明这两个方法。
Single();
Single(const Single& s);
Single& operator=(const Single& s);
private:
static Single* m_single; //之前复习了,static成员变量必须在类外赋值
}
//懒汉模式,只有在getInstance的时候才构建对象,(类外实现m_single静态成员)
Single* Single::m_single = nullptr;
饿汉模式
所谓饿汉模式,就是在对象调用getInstance方法之前就new一个类对象。
#include<iostream>
using namespace std;
class Single{
public:
static Single* getInstance()
{
//饿汉式和懒汉式区别二:饿汉式在类开始被调用之前都创建了对象,不再需要创建的过程,所以是线程安全的。
return sgl;
}
private:
Single() try{
//构建本单例模式的代码
}catch(std::exception& e)
{//处理异常
throw;
}
Single(const Single& s);
Single& operator=(const Single& s);
private:
static Single* sgl;
}
//饿汉式和懒汉式的区别一
Single* Single::sgl = new Single();