有两种模式:
懒汉模式:第一次使用的时候才初始化,需要手动实现线程安全。
恶汉模式:程序一开始就初始化,这个可以自动实现线程安全。
原理都是:把构造函数设置为私有,添加一个私有的静态成员指针变量,添加一个public getInstance方法获取指针来使用。
比较常遇到的问题,就是,使用普通指针的话,需要人为的delete,不过如果这个单例对象,需要执行到程序结束的话,也可以由操作系统回收内存。不过这样的话,虽然内存是回收了,但是析构函数是没有执行的,如果你的析构函数里面需要执行一些io操作什么的,那就泡汤了,这个时候,可以引入一个智能指针,这样,在程序结束的最末,会自动析构。目前,自己写一个日志类(使用缓存)就遇到了需要这个的情况。
遇到的问题是,智能指针的初始化,他不能使用类的私有成员,所以要把那个智能指针设置为友元对象。
懒汉模式,线程安全.
代码语言:javascript复制CMyThreadPool * CMyThreadPool::getInstance()
{
if( NULL == m_pool){
//lock();
std::lock_guard<std::mutex> l(*singal_mutex);
if( NULL == m_pool){
m_pool = new CMyThreadPool();
}
//unlock();
}
return m_pool;
}
class CMyThreadPool
{
private:
...
public:
~CMyThreadPool(void);
static CMyThreadPool * getInstance();
...
private:
CMyThreadPool(void);
...
static CMyThreadPool * m_pool;
...
};
恶汉模式下,采用普通指针和只能指针.
代码语言:javascript复制#include <iostream>
#include <memory>
using namespace std;
class SingletonStatic
{
private:
static const SingletonStatic* m_instance;
static shared_ptr<SingletonStatic> n_instance;
SingletonStatic(){
cout << "hello sig"<<endl;
}
public:
//声明友元对象
friend shared_ptr<SingletonStatic>;
~SingletonStatic(){
cout << "good bye" << endl;
}
static const SingletonStatic* getInstance()
{
return m_instance;
}
static const shared_ptr<SingletonStatic> getNewInstance(){
return n_instance;
}
};
//外部初始化 before invoke main
const SingletonStatic* SingletonStatic::m_instance = new SingletonStatic();
//这里就可以调用他的私有构造函数了
shared_ptr<SingletonStatic> SingletonStatic::n_instance(new SingletonStatic);
int main(){
//需要手动析构普通指针。
delete SingletonStatic::getInstance();
system("pause");
}