设计模式之单例模式

概述

对类的实例化只进行一次,即运行内存中只加载一次该类,需要该类向外提供唯一的访问接口。嵌入式Qt开发中软键盘的类以及通用的日期时间组件等需要用到该模式。

关键点

单例类有且仅有一个实例

单例类必须自行创建自己的唯一实例

单例类必须给所有其它对象提供这一实例

应用

1.局部静态变量方式

singClass.h文件中:

#ifndef SINGCLASS_H
#define SINGCLASS_H

/*实现 */
//提供一个private构造函数(防止外部调用而构造类的实例)
//提供一个该类的static private对象
//提供一个static public 函数,用于创建或获取其本身的静态私有对象(getInstance())

//线程安全问题,资源释放问题
//局部静态变量资源自动释放

class singClass
{
public:
    //向外提供唯一的实例化
    static singClass* getInstance(){
        static singClass instance;
        return &instance;
    }
    //验证测试成功函数,可替换为业务函数
    int sum(int a,int b){
        return a+b;
    }

private:
    singClass(){}//构造函数私有化防止外部调用
};

#endif // SINGCLASS_H

实际调用时:

#include <iostream>
#include "singclass.h"

using namespace std;

int main()
{
    singClass* test=singClass::getInstance();
    int c=test->sum(2,7);
    cout << "return value is:" <<c;
    return 0;
}

2.懒汉方式

singClass.h文件中:

#ifndef SINGCLASS_H
#define SINGCLASS_H

#include <iostream>
#include <mutex>

using namespace std;
/*单例-懒汉(双检锁DCL机制)方式实现 */
//第一次调用时才初始化,避免内存浪费
//需要加锁才能保证线程安全,但加锁会影响效率
//资源释放,一般采用程序自动释放,更加方便


class singClass
{
public:
    //向外提供唯一的实例化
    static singClass* getInstance(){
        if(m_instance == nullptr)
        {
            std::lock_guard<std::mutex> lock(m_mutex);//自解锁
            if(m_instance == nullptr){
               m_instance=new singClass();
            }
        }
        return m_instance;
    }
    //验证测试成功函数,可替换为业务函数
    int sum(int a,int b){
        return a+b;
    }
    //程序自动去释放资源
    class CG{
      public:
        ~CG(){
            //可以在这里释放需要释放的资源
            if(nullptr != m_instance){
                cout << "delete m_instance"<<endl;
                delete m_instance;
                m_instance=nullptr;
            }
        }
    private:
        static CG cg;
    };

private:
    singClass(){}//构造函数私有化防止外部调用
    static singClass *m_instance;
    static mutex m_mutex;
};

singClass * singClass::m_instance=nullptr;//重要
singClass::CG singClass::CG::cg;
mutex singClass::m_mutex;

#endif // SINGCLASS_H

实际调用同方式1

结果如下图所示

控制台执行结果图

3.饿汉方式

singClass.h文件中:

#ifndef SINGCLASS_H
#define SINGCLASS_H

#include <iostream>

using namespace std;
/*单例-饿汉方式实现 */
//类加载时就初始化,浪费内存
//多线程安全,不需要加锁,执行效率会提高
//资源释放,一般采用程序自动释放,更加方便


class singClass
{
public:
    //向外提供唯一的实例化
    static singClass* getInstance(){
        return m_instance;
    }
    //验证测试成功函数,可替换为业务函数
    int sum(int a,int b){
        return a+b;
    }
    //程序自动去释放资源
    class CG{
      public:
        ~CG(){
            //可以在这里释放需要释放的资源
            if(nullptr != m_instance){
                cout << "delete m_instance"<<endl;
                delete m_instance;
                m_instance=nullptr;
            }
        }
    private:
        static CG cg;
    };

private:
    singClass(){}//构造函数私有化防止外部调用
    static singClass *m_instance;
};

singClass * singClass::m_instance=new singClass();//重要
singClass::CG singClass::CG::cg;

#endif // SINGCLASS_H

实际调用同方式1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值