C++单例模式

拜拜、爱过 提交于 2019-11-29 19:16:41

C++单例模式

单例类,顾名思义就是类对象实例唯一,不会被重复多次构造。

划重点

1、构造函数私有化,防止外部调用构造类的实例;
2、提供一个静态私有对象,用于访问自身;
3、提供一个 static public 函数,用于创建或获取其本身的静态私有对象;
4、涉及到多线程时,线程安全问题;
5、资源释放。

懒汉式 and 饿汉式

懒汉式

// singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H

#include <QMutex>

// 单例 - 懒汉式/饿汉式公用
class Singleton
{
public:
    static Singleton* GetInstance();

private:
    Singleton() {}  // 构造函数(被保护)
    Singleton(Singleton const &);  // 无需实现
    Singleton& operator = (const Singleton &);  // 无需实现
    
private:
    static Singleton *m_pSingleton;  // 指向单例对象的指针
    static QMutex m_mutex;  // 锁
};

#endif // SINGLETON_H
// singleton.cpp
#include "singleton.h"

// 单例 - 懒汉式
Singleton *Singleton::m_pSingleton = nullptr;
QMutex Singleton::m_mutex;

Singleton *Singleton::GetInstance()
{
    if (!m_pSingleton) {
        Singleton::m_mutex.lock();
        if (!m_pSingleton) {
            Singleton::m_pSingleton = new Singleton();
        }
        Singleton::m_mutex.unlock();
    }
    return Singleton::m_pSingleton;
}

优点:第一次调用才初始化,避免内存浪费。
缺点:非多线程安全。必须加锁才能保证单例,但加锁会影响效率。

饿汉式

// singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H

// 单例 - 懒汉式/饿汉式公用
class Singleton
{
public:
    static Singleton* GetInstance();

private:
    Singleton() {}  // 构造函数(被保护)
    Singleton(Singleton const &);  // 无需实现
    Singleton& operator = (const Singleton &);  // 无需实现

private:
    static Singleton *m_pSingleton;  // 指向单例对象的指针
};

#endif // SINGLETON_H
// singleton.cpp
#include "singleton.h"

// 单例 - 饿汉式
Singleton *Singleton::m_pSingleton = new Singleton();

Singleton *Singleton::GetInstance()
{
    return m_pSingleton;
}

优点:多线程安全。没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。

资源释放

资源释放分两种:
1、主动释放(手动调用接口来释放资源);
2、自动释放(由程序自己释放)。
要手动释放资源,添加一个 static 接口:

// 单例 - 主动释放
static void DestoryInstance()
{
    if (m_pSingleton != nullptr) {
        delete m_pSingleton;
        m_pSingleton = nullptr;
    }
}

然后在需要释放的时候,手动调用该接口:

Singleton::GetInstance()->DestoryInstance();

----这里是一个单例模板

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!