c++ 单例模式的写法–笔记
大佬的更好的总结在:知乎文章
#ifndef SINGLE_TON_HH
#define SINGLE_TON_HH
#include <string>
namespace ThreadNamespace
{
class SingleTon
{
SingleTon();
~SingleTon();
SingleTon(const SingleTon&) = delete;
SingleTon& operator=(const SingleTon&) = delete;
public:
std::string name;
void myPrint(const std::string& n);
//C++11规定了local static在多线程条件下的初始化行为,
//要求编译器保证了内部静态变量的线程安全性。
/*******************在C++11标准下*******************/
//《Effective C++》提出了一种更优雅的单例模式实现,
//使用函数内的 local static 对象。这样,只有当第一次访问getInstance()方法时才创建实例。
//这种方法也被称为Meyers' Singleton
static SingleTon& getInstance()
{
static SingleTon instance;
return instance;
}//c++11 之后最优雅的单例模式: 返回局部变量的引用.
};
// class SingleTon
// {
// static SingleTon* inst; // 这种写法是线程不安全的
// SingleTon();
// ~SingleTon();
// SingleTon(const SingleTon&) = delete;
// SingleTon& operator=(const SingleTon&) = delete;
// public:
// std::string name;
// void myPrint(const std::string& n);
// static SingleTon* getInstance()
// {
// if(inst != nullptr)
// {
// return inst;
// }
// return inst = new SingleTon();
// }
// };
}
#endif
#include <iostream>
#include "SingleTon.hh"
using namespace std;
namespace ThreadNamespace
{
// SingleTon* SingleTon::inst = nullptr;
SingleTon::SingleTon()
:name("")
{
std::cout<<"构造------------------------------------------------------------------------------>单例."<<std::endl;
}
SingleTon::~SingleTon()
{
std::cout<<"析构******************************************************************************单例!"<<std::endl;
}
void SingleTon::myPrint(const std::string& n)
{
std::cout<< (name.empty() ? n : name) <<std::endl;
}
}
int main(void)
{
std::vector<std::thread> pool;
for(int i = 0; i<100; i++)
{
pool.emplace_back(
std::thread(
[](int k, const std::string& str){
std::cout<<"k is "<< k <<" ;"<< str <<" .thread_id: "<< std::this_thread::get_id() <<std::endl;
SingleTon::getInstance().name = "";
SingleTon::getInstance().myPrint("璃月");
},
i,
"=="
)
);
}
//join()
for(auto& iter : pool)
{
if(iter.joinable())
{
iter.join();
}
}
return 0;
}
关于懒汉式,原生指针的写法是线程不安全且有内存泄漏的(至少在linux上是):
class SingleTon
{
static SingleTon* inst; // 这种写法是线程不安全的
SingleTon();
~SingleTon();
SingleTon(const SingleTon&) = delete;
SingleTon& operator=(const SingleTon&) = delete;
public:
std::string name;
void myPrint(const std::string& n);
static SingleTon* getInstance()
{
if(inst != nullptr)
{
return inst;
}
return inst = new SingleTon();
}
};
SingleTon* SingleTon::inst = nullptr;
SingleTon::SingleTon()
:name("")
{
std::cout<<"构造------------------------------------------------------------------------------>单例."<<std::endl;
}
SingleTon::~SingleTon()
{
std::cout<<"析构******************************************************************************单例!"<<std::endl;
}
void SingleTon::myPrint(const std::string& n)
{
std::cout<< (name.empty() ? n : name) <<std::endl;
}
int main(void)
{
std::vector<std::thread> pool;
for(int i = 0; i<100; i++)
{
pool.emplace_back(
std::thread(
[](int k, const std::string& str){
std::cout<<"k is "<< k <<" ;"<< str <<" .thread_id: "<< std::this_thread::get_id() <<std::endl;
SingleTon::getInstance()->name = "";
SingleTon::getInstance()->myPrint("璃月");
},
i,
"=="
)
);
}
//join()
for(auto& iter : pool)
{
if(iter.joinable())
{
iter.join();
}
}
return 0;
}
出错的结果:构造了两次