单例模式的饿汉和懒汉写法(基于C++)

news/2024/7/3 5:56:07

目录

  • 单例模式
  • 例程
    • 饿汉
    • 懒汉
  • 对比
    • 函数调用
    • 线程安全
    • 总结


单例模式

单例模式确保一个类只有一个实例,并提供全局访问点。这样可以避免在系统中出现多个相同的对象,从而提高系统的性能和可维护性。
单例模式的实现包括饿汉和懒汉,下面介绍C++中这两种方式的写法。

例程

饿汉

饿汉模式是在程序启动前创建实例。
下面是一个全局计数器的示例。
counter.h

class Counter
{
public:
    static void plus(int number);
    static void print();

private:    //method
    Counter();

private:    //member
    static Counter counter;
    int value { 0 };
};

counter.cpp

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

using namespace std;

Counter::Counter()
{
    cout << "init Counter" << endl;
}

Counter *Counter::instance()
{
	return &counter;
}

void Counter::plus(int number)
{
    counter.value += number;
}

void Counter::print()
{
    cout << counter.value << endl;
}

调用

#include "counter.h"

int main()
{
    cout << "program run" << endl;
    Counter::plus(5);
    Counter::print();
    
    return 0;
}

在这里插入图片描述

懒汉

懒汉模式是在第一次获取实例时调用。
同样是刚刚的例子。
counter.h

class Counter
{
public:
    static Counter* instance();
    void plus(int number);
    void print();

private:    //method
    Counter();

private:    //member
    int value{ 0 };
};

counter.cpp

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

using namespace std;

Counter* Counter::instance()
{
    static Counter* counter = NULL;
    if (counter == NULL)
        counter = new Counter;
    return counter;
}

Counter::Counter()
{
    cout << "init Counter" << endl;
}

void Counter::plus(int number)
{
    value += number;
}

void Counter::print()
{
    cout << value << endl;
}

调用

#include "counter.h"

int main()
{
    cout << "program run" << endl;
    Counter::instance()->plus(5);
    Counter::instance()->print();
    
    return 0;
}

在这里插入图片描述

对比

通过上面的例子我们可以看到,饿汉模式和懒汉模式有以下区别。

函数调用

Counter::plus(5);
Counter::print();

Counter::instance()->plus(5);
Counter::instance()->print();

懒汉需要经过实例化函数instance()才能调用方法,饿汉不需要,显然饿汉模式更方便客户端的使用,且效率更高。

线程安全

懒汉是获取实例时才实例化,存在一个线程安全的问题:主线程和子线程同时调用instance()。显然这是不安全的,所以如果这个单例是多线程共享的,那还要加锁,进一步地降低了效率。

总结

通过以上对比,一般来说饿汉会比懒汉要好一些,但如果需要加载的单例很多,耗时比较长,这时候可以考虑使用懒汉。


http://lihuaxi.xjx100.cn/news/1117215.html

相关文章

汽车轮胎充电宝打气泵方案

我们知道新能源车是没有配置充气泵的&#xff0c;所以在平时日常使用中我们还需要配置一个充气泵。充气泵方案便是在这个用户需求上面开发出来的。它体积小、外观精美、带有多模式充气并车胎检测等功能&#xff0c;是现在有车一族的出行必备物品。 充气泵方案其功能设计集成于一…

k8s巡检脚本

#!/bin/bash #检查kubectl是否已经安装 if ! command -v kubectl &> /dev/null then echo -n "kubectl 未安装&#xff0c;请先安装kubectl"exitfi echo -e “开始集群状态信息收集/” #检查集群状态: echo -n “检查集群正常状态:” kubectl cluster…

SSD系列2——PriorBox

SSD系列&#xff1a; SSD系列1——网络结构 SSD系列2——PriorBox SSD系列3——损失计算 PriorBox SSD采用PriorBox来进行区域生成&#xff0c;其思想与Faster RCNN的Anchor类似。PriorBox的本质是在原图上的一系列矩形框&#xff0c;即特征图上的一个点根据下采样率可以得到在…

【深入理解redis】数据结构

文章目录 动态字符串SDS字符串编码类型 intsetDictZipListZipList的连锁更新问题 QuickListSkipListRedisObjectStringListSet结构ZSETHash Redis 共有 5 种基本数据结构&#xff1a;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;…

树结构 数据可视化

这边有个 树结构数据&#xff0c;想做一个可视化展示的需求&#xff1b;首先想到的是 python pyecharts, 一直传说 python 做数据可视化 一把梭&#xff1b; pyecharts 在线实例展示 pyecharts 官网 当看到上面的 示例 后&#xff0c;这不就我想找的嘛&#xff01;哈哈 随后 找…

KingbaseES V8R6 最老事务阻止vacuum freeze

前言 最近生产环境发生几次由于长事务导致表、库年龄没法回收的情况。我们要规避这种情况的发生&#xff0c;不要等发生了再去强制中断会话连接。 当数据库中存在最老事务版本xmin&#xff0c;那么早于他的快照可以被标记为frozen&#xff0c;如果在最老事务之后产生的快照版本…

纽扣电池/含纽扣电池商品亚马逊美国澳洲站点合规认证要求!

纽扣电池/含纽扣电池商品亚马逊美澳站点合规认证 亚马逊美国站纽扣电池&#xff08;含纽扣电池产品&#xff09;合规要求标准&#xff1a; 16CFR1700.15部分(防毒包装标准) 16CFR1700.20部分(特殊包装的检测程序) ANSI C18.3M(便携式锂原电池的安全标准) 警示标签声明要求(…

AI别来搅局,chatGPT的世界不懂低代码

ChatGPT单月访问量再创新高 根据SimilarWeb统计&#xff0c;ChatGPT上月全球访问量17.6亿次&#xff0c;已超越必应、鸭鸭走DuckDuckGo等其他国际搜索引擎&#xff0c;并达到谷歌的2%&#xff0c;百度的60%。 这会&#xff0c;程序员失业的段子又得再来一遍了&#xff1a; 拖…