C++ 设计模式 之 单例模式

简述
        单例模式是设计模式中最简单的形式之一。其目的是使得类的一个对象成为系统中的唯一的实例。
        这种模式设计到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象的方式,可以直接访问,不需要实例化该类的对象。

要点
        单例模式的要点有三个:
            单例模式有且仅有一个实例
            单例类必须自行创建自己的唯一示例
            单例类必须给所有其他对象提供这个示例
        
        从具体实现角度来说,可分为以下三点:
            提供一个private构造函数(防止外部调用而构造类的实例)
            提供一个该类的static private对象
            提供一个static public函数,用于创建或获取其本身的静态私有对象(例如:GetInstance())

        除此之外,还有一些关键点(需要多加注意,很容易忽视):
            线程安全(双检锁-DCL,即:double-checked locking)
            资源释放

实现方法:
        第一种:       
 
 
 
 
#include <iostream>
#include <mutex>//使用局部变量,返回指针

class SignalInstance
{
public:
    static SignalInstance* GetInstance()
    {
        static SignalInstance ins;
        return &ins;
    }
    void disp()
    {
        std::cout << "hello Signal" << std::endl;
    }
private:
    SignalInstance() {}
};

        第二种:
 
 
 
 
#include <iostream>
#include <mutex>

class SignalInstance
{
public:
    static SignalInstance* GetInstance() // 一个公有的静态函数,调用构造函数,获取静态的类对象的指针
    {    
        std::unique_lock<std::mutex> ulk(m_mutex); //加锁,防止多线程中出现不是单例的情况
        if (m_sni == nullptr)
        {
            m_sni = new SignalInstance();
        }
        return m_sni;
    }
    
    void disp() // 一个普通的测试函数
    {
        std::cout << "hello Instance" << std::endl;
    }

private:
        static SignalInstance *m_sni; //静态函数只能调用静态的成员变量
        static std::mutex m_mutex;
        
        class Fre // 在类的内部创建一个私有的类,专门用作 对象的释放,当函数返回时,会自动调用它的析构函数,从而释放单例对象
        {
        public:
            ~Fre()
            {
                if (m_sni != nullptr)
                {
                    delete m_sni;
                    m_sni = nullptr;
                }
            }
            static Fre fr;
        };

private:
    SignalInstance() {}  // 将构造函数写为私有方法,防止其他类的调用
};

SignalInstance* SignalInstance::m_sni = nullptr;
SignalInstance::Fre SignalInstance::Fre::fr; // 为了自动,必须要这句,否则无法析构
std::mutex SignalInstance::m_mutex;

// 测试代码
int main()
{
    SignalInstance *ins = SignalInstance::GetInstance();     
    ins->disp();     
    getchar();
    return 0;
}




猜你喜欢

转载自blog.csdn.net/zyx_0604/article/details/80731725
今日推荐