C++ 单例模式

2020-10-10 16:41:51 浏览数 (1)

有两种模式:

懒汉模式:第一次使用的时候才初始化,需要手动实现线程安全。

恶汉模式:程序一开始就初始化,这个可以自动实现线程安全。

原理都是:把构造函数设置为私有,添加一个私有的静态成员指针变量,添加一个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");
}

0 人点赞