C++ 单例模式_c++单例模式-CSDN博客
文章内容来自上面的文章
#include
#include "widget.h"
using namespace std;
/*
* 版本1 SingletonPattern_V1 存在以下两个问题
*
* 1. 线程不安全, 非线程安全版本
* 2. 内存泄露
*/
class SingletonPattern_V1
{
private:
SingletonPattern_V1() {
cout << "constructor called!" << endl;
}
SingletonPattern_V1(SingletonPattern_V1&) = delete;
SingletonPattern_V1& operator=(const SingletonPattern_V1&) = delete;
static SingletonPattern_V1* m_pInstance;
public:
~SingletonPattern_V1() {
cout << "destructor called!" << endl;
}
//在这里实例化
static SingletonPattern_V1* Instance() {
if (!m_pInstance) {
m_pInstance = new SingletonPattern_V1();
}
return m_pInstance;
}
void use() const { cout << "in use" <use();
p2->use();
return 0;
}
constructor called!
in use
in use
容易知道此时是内存泄漏的
线程安全:
多线程中:
static SingletonPattern_V1* Instance() {
if (!m_pInstance) {
m_pInstance = new SingletonPattern_V1();
}
return m_pInstance;
}
执行该段代码时,if(!m_pInstance),如果线程A和线程B都判断为空,都开始初始化实例,那么会初始化两次.此时需要加锁.
解决问题后的代码:
#include
using namespace std;
#include // C++11 shared_ptr头文件
#include // C++11 mutex头文件
/*
* 版本2 SingletonPattern_V2 解决了V1中的问题
*
* 1. 通过加锁让线程安全了
* 2. 通过智能指针(shareptr 基于引用计数)内存没有泄露了
*/
class SingletonPattern_V2
{
public:
~SingletonPattern_V2() {
std::cout << "destructor called!" << std::endl;
}
SingletonPattern_V2(SingletonPattern_V2&) = delete;
SingletonPattern_V2& operator=(const SingletonPattern_V2&) = delete;
//在这里实例化
static std::shared_ptr Instance()
{
//双重检查锁
if (m_pInstance == nullptr) {
std::lock_guard lk(m_mutex);
if (m_pInstance == nullptr) {
m_pInstance = std::shared_ptr(new SingletonPattern_V2());
}
}
return m_pInstance;
}
private:
SingletonPattern_V2() {
std::cout << "constructor called!" << std::endl;
}
static std::shared_ptr m_pInstance;
static std::mutex m_mutex;
};
//在类外初始化静态变量
std::shared_ptr SingletonPattern_V2::m_pInstance = nullptr;
std::mutex SingletonPattern_V2::m_mutex;
int main()
{
std::shared_ptr p1 = SingletonPattern_V2::Instance();
std::shared_ptr p2 = SingletonPattern_V2::Instance();
system("pause");
return 0;
}
用智能共享指针和锁把上面的问题给解决了.
SingletonPattern_V2(SingletonPattern_V2&) = delete;
C++11中=delete的巧妙用法_= delete-CSDN博客