单例模式:全局唯一实例,提供一个很容易获取这个实例的接口

成都创新互联公司长期为上千余家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为献县企业提供专业的成都网站设计、成都网站制作,献县网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制开发。
线程安全的单例:
懒汉模式(Lazy Loading):第一次获取对象时才创建对象
class Singleton
{
public:
//获取唯一实例的接口函数
static Singleton* GetInstance()
{
//双重检查,提高效率,避免高并发场景下每次获取实例对象都进行加锁
if (_sInstance == NULL)
{
std::lock_guard 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();
}