提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
面向对象很好的解决了抽象问题,但必不可少的要付出一定的代价。
在软件系统中,经常有一些特殊的类,必须保证他们在系统中质询才一个实例,才能保证他们逻辑的正确性以及良好的效率。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Singleton
- 构造函数必须是私有的,不能不写,C++会默认生成public的构造函数和拷贝构造函数;
- 默认关闭赋值操作、拷贝构造和右值;
- public里面声明静态指针和静态函数方法,返回这个类唯一实例指针;
class Singleton
{
private:
Singleton();
Singleton(const Singleton &other)=delete;
Singleton &operator=(const Singleton &other) = delete;
Singleton(Singleton &&other) = delete;
Singleton &operator=(Singleton &&other) = delete;
~Singleton();
public:
static Singleton *getInstance();
static Singleton *m_instance;
}
// 初始化指针为nullptr
Singleton *Singleton::m_instance = nullptr;
// 线程非安全版本, 多线程可能会创建两个以上实例
Singleton *Singleton::getInstance()
{
if (m_instance == nullptr)
{
m_instance = new Singleton();
}
return m_instance;
}
// 线程安全版本, 但锁的代价过高
Singleton *Singleton::getInstance()
{
Lock lock;
if (m_instance == nullptr)
{
m_instance = new Singleton();
}
return m_instance;
}
// 双检查锁, 但由于内存读写recorder不安全
Singleton *Singleton::getInstance()
{
if (m_instance == nullptr)
{
Lock lock;
if (m_instance == nullptr)
{
m_instance = new Singleton();
}
}
return m_instance;
}
// C++ 11版本之后的跨平台实现 (volatile)
std::atomic<Singleton *> Singleton::m_instance;
std::mutex Singleton::m_mutex;
Singleton *Singleton::getInstance()
{
Singleton *instance = m_instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire); // 获取内存defence, 保证CPU没有reorder优化
if (instance == nullptr)
{
std::lock_guard<std::mutex> lock(m_mutex);
instance = m_instance.load(std::memory_order_relaxed);
if (instance == nullptr)
{
instance = new Singleton();
m_instance.store(instance, std::memory_order_release); //释放内存defence
}
}
return instance;
}