一个真正的Singleton

webpack5模块联邦(Module Federation)使用教程,在vue2中使用 使用vue2组件,演示webpack5中模块联邦(Module Federation)的使用,以及如果优化依赖。 阅读详情

对于单件模式, 我想大家应该都不陌生,它可以说是GOF23个设计模式中最简单,最常用的一个模式了。但看似简单的东西却不一定好用,我就在使用时遇到了一个问题。

 

1       一个简单的Singleton类

我们先来看一个简单的单件类的定义:

#include<iostream>

class Singleton

{

public:

static Singleton& GetSingleton()

{

    static Singleton singleton;

    return singleton;

}

 

void Print()

{

    std::cout<<"Singleton Print/n";

}

 

private:

Singleton::Singleton()

{

    std::cout<<"singleton constructor/n";

}

};

这个类提供了一些的功能(函数Print), 并禁止我们创建这个类的对象(构造函数为private), 提供给我们一个静态函数接口来访问这个单件对象(GetSingleton),利用静态变量的特点实现了其单一性。但是, 这个类有问题吗?

2       问题所在

是的,上面这个简单的类的确存在问题,而且是一个很严重的问题,这个问题让Singleton类完全失去它存在的意义, 因为它不再唯一!

是的, 当我们只在一个模块中使用这个类时(比如说,一个exe),这个类是没有问题的。但是, 一个稍微复杂一点的软件, 为了开发的便捷,提高复用度,降低耦合性等原因,其难免会被分成好几个模块。那么假设讲我现在有两个模块,一个DLL(singleton.dll), 用来提供一些基础的功能, 一个EXE(test.exe),用来提供真正的软件逻辑。 我现在singleton.dll中封装了一个Print的函数间(用类Singleton实现)并暴露出来。

singleton.dll

void Print()

{

    Singleton::GetSingleton().Print();

}

并在test.exe中这样调用:

Test.exe

Singleton::GetSingleton().Print();

Print();

这个时候,我们会发现在调用Singleton::GetSingleton().Print()时会产生一个Singleton对象, 而在调用Print()时, 也会产生一个Singleton对象, 也就是说我们有了两个Singleton实例, singleton不再是singleton。那么, 为什么会这样呢。

static Singleton& GetSingleton()

{

    static Singleton singleton;

    return singleton;

}

这个函数应该只会在第一次调用时创建Singleton对象,无论如何, 不应该出现会创建两次, 调用两次构造函数的情况。对于静态变量特性理解没错(只在第一次经过时被初始化), 编译器也没问题(vc8.0),难道两次经过该静态变量是都是第一次? 那么,难道两次调用的GetSingleton函数并不是同一个函数?让我们逐一来看:

1) Singleton::GetSingleton().Print()

在Test.exe中直接调用该函数,因为包含的头文件singleton.h有完整的实现, 在链接时会在Test.exe保存一份Singleton::GetSingleton()的实现代码。

将其标为Singleton::GetSingleton_1();

2) Print();

Print()函数是从singleton.dll中导出而来的,而Print()会调用Singleton::GetSingleton(), 在链接模块singleton.dll时,因为其包含的头文件有完整的实现, 这个DLL也会保存一份Singleton::GetSingleton()的执行代码。 我将它标为Singleton::GetSingleton_2(), 虽然我们包含的是同一个头文件,两个是相同的函数名字, 但是这个函数在两个不同的模块中都存有一份独立的实现。实际上, 他们已经成为两个不同的函数了。

看来,两个函数的确不是同一个函数。

 

3       如何解决

既然知道了原因,就会有相应的解决方法。既然我们知道有两份独立的代码分别存在于两个模块中, 那么我们要做的就是让它只有一份。最好的结果就是这个函数保存在dll中, 在Test.exe不再存有该函数的执行代码, 而是调用dll中的那个函数。现在结果很明显了:将Singleton.h编译链接singleton.dll并将外部需要使用的函数暴露出来。这样, 不管有多少模块使用到singleton, 我们始终执行singleton.dll中的代码。

如下:

SINGLETON_API static Singleton& GetSingleton()

{

     static Singleton singleton;

     return singleton;

}

注:

#ifdef SINGLETON_EXPORTS

#define SINGLETON_API __declspec(dllexport)

#else

#define SINGLETON_API __declspec(dllimport)

#endif

这样在test.exe中使用该函数时,就不会再产生一个副本了,从而保证了我们的应用程序只有一个singleton实例

写一个 Singleton Singleton 模式主要作用是保证在 Java 应用程序中,一个类 Class 只有一 个实例存在。举例:定义一个类,它的构造函数为 private 的,它有一个 static 的 private 的该类变量,在类初始化时实例化,通过一个 public 的 getInstance 方法获取对它的引用,继而调用其中的方法。 //第一种形式 public class Singleton 阅读详情

相关推荐

告别LM2596!用LM5175打造400W自动升降压数控电源(附完整电路图与代码)

本文详细介绍了如何利用LM5175芯片设计400W自动升降压数控电源,替代传统的LM2596方案。通过四开关Buck-Boost拓扑结构,LM5175实现了高达98%的转换效率和400W大功率输出,支持无缝升降压切换。文章涵盖芯片选型、电路设计、PCB布局及STM32数控实现,为工程师提供完整的实践指南。

weixin_27032989的博客 598

odoo异常:Expected singleton: res.users()

添加with_user(即可) #如下列这一条报错: task.message_post(body = "消息") #改成以下这样: from odoo import SUPERUSER_ID task.with_user(SUPERUSER_ID).message_post(body = "")

qq_41042860的博客 600

遥感SCI期刊模板下载教程———IEEE TGRS、GRSL、JSTARS

IEEE下的期刊模板下载,以IEEE TGRS 为例。

海淀小天的blog 2万+

报错:Expected singleton

一.Expected singleton 在学习中遇到了如下报错: ValueError: Expected singleton: ir.model.data(19897, 21168) 这是返回一个数据,却找到了多个数据所导致的错误.如果在学习中遇到,就应该排查一些方法,观察是否没有指定具体的模块等. ...

m0_56227168的博客 1084

基于MicroBlaze与LWIP的FPGA以太网通信实战指南

本文详细介绍了基于MicroBlaze软核处理器与LWIP协议栈的FPGA以太网通信实现方案。通过Vivado工具链配置硬件设计,结合LWIP轻量级TCP/IP协议栈优化,提供高效、低成本的嵌入式网络解决方案,适用于工业控制等场景。文章包含硬件设计、软件配置及常见问题排查等实战指南。

weixin_29290863的博客 532

微信小程序 - 详细实现随机生成订单号,微信小程序创建订单号思路,不重复订单号生成的方法,小程序自动生成固定规则的订单号流水号(必须是唯一不重复的订单号,生成唯一订单号)详细生成方法,示例代码教程最新

微信小程序,vue2,vue3,订单号,流水号思路,微信小程序 详细实现随机生成订单号(JavaScript),随机生成商户订单号,根据当前时间随机生成流水号或者订单号,微信小程序之商家订单,订单号随机生成器,自动生成固定规则的订单号(前缀+采购日期+6位流水号)微信小程序 生成外卖顺序号,生成订单号或流水号简单方法,实现订单号生成唯一的解决方案,如何按日期生成订单号,14位编号=8位日期(+6位流水号),自动生成订单号(固定+日期+数字),销售订单号自动生成。在微信小程序开发中,详解实现随机生成创建订单号

🏆 前端领域优质创作者 1186

ValueError: Expected singleton: hw.rebuild.exam(6, 3)

ValueError: Expected singleton: hw.rebuild.exam(6, 3)

weixin_48413201的博客 296

Attention优化|2w字原理&图解: 从Online-Softmax到FlashAttention V1/V2/V3

本文通过原理分析和图解的方式,通俗易懂地FlashAttention系列算法。FlashAttention V1/V2在LLM领域的应用已经非常广泛,相关的论文也反复读了几遍。FA1和FA2论文非常经典,都推荐读一下(不过FA2论文中公式错误不少本文大约1.8w字,包括以下内容:0x07 分布式训推使用FlashAttention0x09 FlashAttention中MQA/GQA以及Causal Mask处理。

具身机器人和通用AI 5232

odoo开发笔记--ValueError Expected singleton

异常处理参考:https://stackoverflow.com/questions/31070640/valueerror-expected-singleton-odoo8 报错:ValueError Expected singleton: ******* 原因是,odoo几个装饰器的使用需要注意,当你后台方法用了@api.multi,那么,该方法下的数据,需要for循环遍历一下...

weixin_30300523的博客 1352

2025年全国青少年信息素养大赛初赛真题(算法创意实践挑战赛C++初中组:文末附答案)

2025年全国青少年信息素养大赛初赛真题(算法创意实践挑战赛C++初中组:文末附答案)

王老师青少年编程 3396

泛微OA提交流程到下一个节点

泛微OA后端接口强制流程归档

CXYCMY的博客 2246

编程题: 写一个Singleton

Singleton模式 Singleton可以说是《Design Pattern》中最简单也最实用的一个设计模式。那么,什么是Singleton? 顾名思义,Singleton就是确保一个类只有唯一的一个实例。Singleton主要用于对象的创建,这意味着,如果某个类采用了Singleton 模式,则在这个类被创建后,它将有且仅有一个实例可供访问。很多时候我们都会需要Singleton模式,最

u012872026的专栏 1904

S/4HANA Private Cloud 与 On-Premise 的 Key User Custom Fields 运输与升级避坑指南

本文探讨了SAP S/4HANA Cloud Private Edition和On-Premise系统中Key User Custom Fields的管理要点。文章指出,Custom Fields涉及元数据生成、对象一致性、传输治理等完整链路,操作不当会导致字段丢失或升级失败。关键建议包括:使用ATO Fiori App管理扩展项与传输绑定,配置正确的job user权限,避免在多系统并行开发同一字段。特别强调升级时需执行CFD_REGENERATE_IN_ONPREMISE报表,并通过标准传输机制推进变更

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 195

编写一个singleton出来

package bi.shi.demo; /** * @program: bi_shi_test * @description: 编写一个singleton出来 * @author: xin yi * @create: 2021-09-11 11:16 */ public class Singleton { public static void main(String[] args) { MainWindow mainWindow = new MainWindow();.

xinyi_java的博客 313

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

写一个Singleton出来

      Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。      public class Singleton {   private static Singleton instance = null;   public static synchronized Singleton getInstance() {   //这个方法比上面有所改进,

javaws的专栏 3250

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

写一个Singleton出来。

Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。一般Singleton模式通常有几种种形式:第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。public class Singleton {pri

l_rui_ci的专栏 402

Singleton的一个基类实现

    在创建型模式中,有一种设计模式“Singleton”。该模式的意图是,保证一个类仅有一个实例,并提供一个访问它的全局访问点。在GOF的指导下,我们经常写一些Singleton类。每个类很类似。   以下代码描述了一个Singleton的基类及使用方法:template class T>class AllocUsingNew {public:    static T*

Blue Light的专栏 C++,OOA/D/P 2512

一个简单的Singleton

下面是一个   package com.seimma.singleton; public class Singleton { //使用一个静态常量缓存曾经创建的实例    private static Singleton instance;    //将构造器修饰符改成private,隐藏该构造器,创建Singleton对象只能通过实例创建。    private Singleton(){ ...

金佳杰 175

一个写Singleton类的简易方法

发现 http://gforge.osdn.net.cn是个不错的东东,暂时东西还比较少,需要大家多多共享,浏览中发现一个超简易的工具来实现Singleton模式的类,贴出来与大家共享。 http://gforge.osdn.net.cn/snippet/detail.php?type=snippet&id=16其中,使用了两种方式来实现Singleton,一种是在QT下的实现,一种是在标

891

bean定义是一个singleton还是一个prototype。

singleton和prototype的区别singleton作用域:当把一个Bean定义设置为singleton作用域是,Spring IoC容器中只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean定义相匹配,则只会返回该Bean的同一实例。值得强调的是singleton作用域是Spring中的缺省作用域。prototype作用域:prototype作用域的Bean会...

qq_35334804的博客 813

89、编程题: 写一个Singleton出来。

89、编程题: 写一个Singleton出来。 Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 一般Singleton模式通常有几种种形式: 第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。 Public class Singleton { private Singleton(){}    //

kaszxc的博客 333

Spring实现一个singleton bean要引用另外一个非singleton bean

在大部分情况下,容器中的bean都是singleton类型的。如果一个singleton bean要引用另外一个singleton bean,或者一个非singleton bean要引用另外一个非singleton bean时,通常情况下将一个bean定义为另一个bean的property值就可以了。不过对于具有不同生命周期的bean来说这样做就会有问题了,比如在调用一个singleton类型be

luosijin123的专栏 3177

[转载]Singleton的一个基类实现

今天去面试一家游戏公司,笔试题有道叫做 设计并实现一个Singleton基类。以前没有认真考虑过这个问题,转载了一篇。原文地址:http://blog.youkuaiyun.com/Blue_Light/archive/2008/07/13/2646266.aspx 在创建型模式中,有一种设计模式“Singleton”。该模式的意图是,保证一个类仅有一个实例,并提供一个访问它的全局访问点。在GOF的指导...

weixin_30783629的博客 76

一个简单的Singleton 单例模式

SingletonTest.java代码如下: public class SingletonTest { public static void main(String[] args) { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance()...

zhou363667565的专栏 179
上一篇: DLL地狱及其解决方案
下一篇: i.e. e.g. etc.的意思
wang37921
博客等级 码龄18年 14粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值