单例模式详解----懒汉式/饿汉式(C++实现)_写一个饿汉模式c++-程序员宅基地

技术标签: C++  c++  单例模式  设计模式  

单例模式:

       单例模式是一种常用的软件设计模式,它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

单例模式的要求:

  • 构造函数私有化
  • 增加静态私有类指针变量
  • 增加静态公有接口,可以让用户获取单例对象

单例模式基本形式

class A
{
private:
    A(){
        a=new A;
    }
public:
    static A* getInstance(){    
        return a;
    }
private:
    static A* a;
}

//调用
A* A::a=NULL;

单例模式的分类:

懒汉式:直接创建出类的实例化。

            空间换时间,因为上来就实例化一个对象,占用了内存,并不管主程序是否用到该类。

饿汉式:在需要的时候创建类的实例化。

            时间换空间,与饿汉式相反。

懒汉式代码示例

/*懒汉式单例模式*/
class Singleton_lazy{
private:
    /*构造函数私有化,保证不在类的外部实例化*/
    Singleton_lazy(){cout<<"我是懒汉式构造函数"<<endl;}
public:
    /*用户接口,在使用的时候创建一个类的实例化*/
    static Singleton_lazy* getInstance(){
        //判断pSingleton是否为NULL,如果为NULL,即判定需要实例化
        if (pSingleton==NULL){
            pSingleton=new Singleton_lazy;
        }
        return pSingleton;
    }
private:
    static Singleton_lazy* pSingleton;    //静态类对象
};

//静态对象类外初始化
Singleton_lazy* Singleton_lazy::pSingleton=NULL;

饿汉式代码示例

/*饿汉式单例模式*/
class Singleton_hungry{
private:
    Singleton_hungry(){cout<<"我是饿汉式构造函数"<<endl;}
public:
    /*返回已经创建好的类实例*/
    static Singleton_hungry* getInstance(){
        return pSingleton;
    }
private:
    static Singleton_hungry* pSingleton;
};

//类外初始化:直接创建出类的实例 
Singleton_hungry* Singleton_hungry::pSingleton=new Singleton_hungry;

对比测试

在上述懒汉式、饿汉式单例类的基础上进行测试对比:

  • 在主函数中,仅仅创建了懒汉式单例类对象,而在代码运行结果中显然存在饿汉式单例类的构造函数调用结果,说明懒汉式需要在类的外部主动实例化,而饿汉式则在类定义好之后自动实例化
  • 由代码运行结果可知,饿汉式单例类在执行main函数之前就已经实例化调用了构造函数,而懒汉式单例类则是在main函数内部主动实例化时调用构造函数
int main()
{
    cout<<"main函数开始"<<endl;
    Singleton_lazy* p1=Singleton_lazy::getInstance();
    return 0;
}

/*测试代码输出结果*/

我是饿汉式构造函数
main函数开始
我是懒汉式构造函数

对比与选择:

  • 由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。
  • 在访问量较小时,采用懒汉实现。这是以时间换空间。

单例模式与多线程

懒汉式遇到多线程,不是线程安全的。解决方法:加锁。

饿汉式遇到多线程,是线程安全的。 由于在多线程启动前已经创建好类实例对象,不会重新实例化,是线程安全的。

线程安全的懒汉式单例类

/*线程安全的懒汉式单例类*/
class Singleton_lazy{
protected:
    Singleton_lazy()
    {
        pthread_mutex_init(&mutex,NULL);
    }
public:
    static Singleton_lazy* getInstance();
    static pthread_mutex_t mutex;

private:
    static Singleton_lazy* pSingleton;
};

pthread_mutex_t Singleton_lazy::mutex;
Singleton_lazy* Singleton_lazy::pSingleton=NULL;
Singleton_lazy*Singleton_lazy::getInstance()   
{
    if (pSingleton==NULL)
    {
        pthread_mutex_lock(&mutex);
        if(pSingleton==NULL)
            pSingleton=new Singleton_lazy;
        pthread_mutex_unlock(&mutex);
    }
    return pSingleton;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_36316285/article/details/115030424

智能推荐

正点原子bootloader代码(STM32F103ZET6)粗略解读_正点原子f103 bootloader模式-程序员宅基地

文章浏览阅读943次,点赞19次,收藏18次。关于正点原子IAP程序解读_正点原子f103 bootloader模式

多目标麻雀搜索优化算法及其MATLAB实现_多目标麻雀优化-程序员宅基地

文章浏览阅读186次。麻雀搜索优化算法(Sparrow Search Optimization,简称SSO)是一种基于麻雀行为的启发式优化算法,用于解决多目标优化问题。该算法模拟了麻雀在觅食和寻找栖息地过程中的行为,通过群体合作和信息共享来寻找最优解。本文将介绍多目标麻雀搜索优化算法的原理,并提供MATLAB实现的源代码。本文介绍了多目标麻雀搜索优化算法的原理,并提供了MATLAB实现的源代码。通过模拟麻雀的觅食和寻找栖息地行为,该算法在解决多目标优化问题上具有一定的效果。使用时,可以根据具体的多目标优化问题,实现。_多目标麻雀优化

newFixedThreadPool、newSingleThreadPool、newCachedThreadPool线程池创建线程的方式_executors.newfixedthreadpool(5)如何创建多线程-程序员宅基地

文章浏览阅读411次。newFixedThreadPool、newSingleThreadPool、newCachedThreadPool线程池创建线程的方式_executors.newfixedthreadpool(5)如何创建多线程

Java接口幂等性设计场景解决方案v1.0_java 面试场景题解决方案方案-程序员宅基地

文章浏览阅读145次,点赞2次,收藏2次。用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个简单的例子:那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常了,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。在以前的单应用系统中,我们只需要对数据操作加入事务即可,发生错误的时候立即回滚,但是再响应客户端的时候也有可能网络中断或者异常等等情况。_java 面试场景题解决方案方案

A USB HID Component for C#-程序员宅基地

文章浏览阅读5.5k次。 Download source - 262.48 KB IntroductionThis article is about a USB HID component which enables you to communicate with HID devices over USB. There is no default component available for USB_a usb hid component for c#

SpringCloudOAuth2中访问/oauth/token报server_error_spring cloud oauth2中访问 /oauth/token 跳转不到具体方法-程序员宅基地

文章浏览阅读2k次。问题分析在新建的Spring Cloud OAuth2项目中使用grant_type为password方式访问时报server_error。在postman中如下图:{ "error": "server_error", "error_description": "Internal Server Error"}java后台报错如下:endpoint.TokenEndpoint : Handling error: NestedServletException, Handler d_spring cloud oauth2中访问 /oauth/token 跳转不到具体方法

随便推点

java http 请求网页保存导入写入 本地 文件_java http接口获取数据,结果写入文件-程序员宅基地

文章浏览阅读828次。目录依赖调用获取网页写入本地import依赖<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.2</version..._java http接口获取数据,结果写入文件

lists这个类无法使用maven打包_lists maven-程序员宅基地

文章浏览阅读1.6k次。org.assertj assertj-core_lists maven

关于微信小程序打包文件vendor.js超过500k的压缩方案_发行时压缩vendor文件-程序员宅基地

文章浏览阅读5.4k次。关于微信小程序打包文件vendor.js超过500k的压缩方案因为是开发环境,所以没进行UglifyJs压缩,所以解决的方法来了,引入UglifyJs插件修改build目录下 的webpack.dev.conf.js配置文件,前面添加插件的引入,var UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 在插件列表加上一句话,就可将..._发行时压缩vendor文件

C语言--指针详解(下)--字符指针、数组指针、指针数组、函数指针、函数指针数组(转移表)-程序员宅基地

文章浏览阅读1k次,点赞33次,收藏30次。字符指针、数组指针、指针数组、函数指针、函数指针数组涵盖了在指针学习中有关指针的绝大多数的情况,熟练掌握它们,将对学习指针有巨大的帮助。同时,指针部分是C语言学习中重要的部分之一,熟练掌握指针对于C语言学习来说很重要。

心理韧性与青少年的大脑结构、功能和连接-程序员宅基地

文章浏览阅读31次。尽管早期的逆境经历与日后精神病理学风险增加有关,但一些经历过童年期逆境的个体表现出心理韧性。目前对心理韧性的神经相关知之甚少,特别是在青少年群体中。为了填补这一空白,我们对青少年心理韧性的神经影像学研究进行了系统综述。我们检索了PubMed、Web of Science、Scopus和PsycINFO数据库,共确定了5,482项研究。通过筛选标题/摘要,并通读剩余文章,纳入了基于19个独特数据集的22项研究。我们发现初步证据表明,通过结构和功能MRI以及弥散张量成像方法评估,心理韧性与青少年的大脑结构、功能

前端uni-app自定义精美全端复制文本插件,支持全端文本复制插件 可设置复制按钮颜色_uni-app 文本复制-程序员宅基地

文章浏览阅读1.4k次。标题:前端组件化开发之自定义全端复制文本插件一、引言随着前端技术的发展,组件化开发模式越来越受到重视。组件化开发可以将复杂的系统拆分为一系列可重复使用的组件,实现单独开发、单独维护,并可以随意组合,从而提高开发效率和降低维护成本。本文将介绍一款自定义全端复制文本插件,并阐述其在实际应用中的技术细节和优势。二、全端复制文本插件的功能和特点全端复制文本插件是一款可以自定义样式和复制文本内容的插件,支持设置复制按钮的颜色以及自定义复制文本字符。_uni-app 文本复制

推荐文章

热门文章

相关标签