欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++单例模式(Singleton)的实现

程序员文章站 2022-07-14 09:03:38
...

在程序编程中,经常需要某个类在程序的声明周期中只需要一个实例存在,可不同模块*享某个函数接口、功能或数据,这种设计模式被称为单例模式。单例模式的书面定义如下:也叫单子模式,是一种常用的软件设计模式。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例(即一个类只有一个对象实例)。

CSingleton.hpp

#ifndef CCSingleton_hpp
#define CCSingleton_hpp

#include <stdio.h>
#include <pthread.h>
#include <memory>

class CSinGuard {
public:
    CSinGuard() { m_lGrdCnt = 0; pthread_mutex_init(&m_cs, nullptr); }
    ~CSinGuard() { pthread_mutex_destroy(&m_cs); }
    
    int IsGuarded() const { return (m_lGrdCnt > 0); }
    
public:
    class CGuard {
    public:
        CGuard(CSinGuard& rg):m_rg(rg) { m_rg.Guard(); };
        ~CGuard() { m_rg.Unguard(); }
        
    private:
        CSinGuard& m_rg;
    };
    
private:
    void Guard() { pthread_mutex_lock(&m_cs); m_lGrdCnt++; }    //引用+1
    void Unguard() { m_lGrdCnt--; pthread_mutex_unlock(&m_cs); }    //引用-1
    
    friend class CSinGuard::CGuard;
    
private:
    pthread_mutex_t m_cs;   //线程锁
    long m_lGrdCnt;     //引用计数
};

template <class T>
class CSingleton
{
public:
    static inline T* Instance();
    static inline void Release();
    
private:
    CSingleton(void) {}
    ~CSingleton(void) {}
    CSingleton(const CSingleton&) {}
    CSingleton & operator= (const CSingleton &) {}
    
    static std::auto_ptr<T> m_Instance; //智能指针,会自动释放
    static CSinGuard m_sg;   //单例安全锁
};

//声明单例(对象)模板
template <class T>
std::auto_ptr<T> CSingleton<T>::m_Instance;

//声明单例对象安全锁模板
template <class T>
CSinGuard CSingleton<T>::m_sg;

//获取单例
template <class T>
inline T* CSingleton<T>::Instance()
{
    if (m_Instance.get() == nullptr) {
        CSinGuard::CGuard gd(m_sg);      //上锁,防止多线程同时访问
        if (m_Instance.get() == nullptr) {
            m_Instance.reset(new T);
        }
    }
    
    return m_Instance.get();
}

//释放单例
template <class T>
inline void CSingleton<T>::Release()
{
    CSinGuard::CGuard gd(m_sg);
    m_Instance.release();
}

#define DECLARE_SINGLETON_CLASS(Type) \
friend class std::auto_ptr<Type>; \
friend class CSingleton<Type>; \
static Type* Instance() { Type *shareClass = CSingleton<Type>::Instance(); return shareClass; }\
static void Release() { Type *shareClass = CSingleton<Type>::Instance(); if (shareClass ) { delete shareClass; shareClass = nullptr; } CSingleton<Type>::Release(); }

#endif /* CCSingleton_hpp */

使用方法:
1、在需要使用单例的类的头文件中引用单例文件:#include “CSingleton.hpp”
2、在需要使用单例的类中声明为单例类(即引用单例文件的代码块构造成单例模式):DECLARE_SINGLETON_CLASS(该类的名称);

class JMThreadPool
{
public:
    JMThreadPool();
    virtual ~JMThreadPool();
    DECLARE_SINGLETON_CLASS(JMThreadPool);
    
    void TestSingleton() { printf("It is address:%p", this); };
};

3、单例类的调用:

JMThreadPool::Instance()->TestSingleton();

4、单例类的释放:

JMThreadPool::Release();

PS:代码参考了Github上的一篇文章,时间久远,已不记得笔者。若笔者或码友留言提供,我后期再进行添加及备注。