单例模式:全局唯一实例,提供一个很容易获取这个实例的接口
线程安全的单例:
懒汉模式(Lazy Loading):第一次获取对象时才创建对象
class Singleton
{
public:
//获取唯一实例的接口函数
static Singleton* GetInstance()
{
//双重检查,提高效率,避免高并发场景下每次获取实例对象都进行加锁
if (_sInstance == NULL)
{
std::lock_guard<std::mutex> lock(_mtx);
if (_sInstance == NULL)
{
Singleton* tmp = new Singleton;
MemoryBarrier(); //内存栅栏,防止编译器优化
_sInstance = tmp;
}
}
return _sInstance;
}
static void DelInstance()
{
if (_sInstance)
{
delete _sInstance;
_sInstance = NULL;
}
}
void Print()
{
std::cout << _data << std::endl;
}
private:
//构造函数定义为私有,限制只能在类内实例化对象
Singleton()
:_data(10)
{}
//防拷贝
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
private:
static std::mutex _mtx; //保证线程安全的互斥锁
static Singleton* _sInstance; //指向实例的指针定义为静态私有,这样定义静态成员获取对象实例
int _data; //单例类里面的数据
};
饿汉模式(Eager Loading):第一次获取对象时,对象已经创建好。
简洁、高效、不用加锁,但是在某些场景下会有缺陷。
/*方式一*/
class Singleton
{
public:
static Singleton* GetInstance()
{
static Singleton sInstance;
return &sInstance;
}
void Print()
{
std::cout << _data << std::endl;
}
private:
Singleton()
:_data(10)
{}
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
private:
static Singleton* _sInstance;
int _data;
};
void TestSingleton()
{
Singleton::GetInstance()->Print();
}
/*方式二*/
class Singleton
{
public:
static Singleton* GetInstance()
{
static Singleton sInstance;
return &sInstance;
}
static void DelInstance()
{
if (_sInstance)
{
delete _sInstance;
_sInstance = NULL;
}
}
void Print()
{
std::cout << _data << std::endl;
}
private:
Singleton()
:_data(10)
{}
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
private:
static Singleton* _sInstance;
int _data;
};
Singleton* Singleton::_sInstance = new Singleton;
void TestSingleton()
{
Singleton::GetInstance()->Print();
Singleton::DelInstance();
}
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。