C++单例模板:使用宏函数实现
创始人
2024-03-04 15:31:22
0

C++单例模板:使用宏函数实现

  在我们日常开发中,无可避免需要使用单例模式进行设计类对象,那么实际上我们写单例格式基本都是一样的,那么每次都要写几乎一模一样的代码来实现我们需要的单例对象是不是会觉得很累?下面博主提供一种单例模板来完成我们日常设计单例类,提高工作效率。既然封装了,那么当然是封装一个线程安全的单例模板,如下:

ISingleton.hpp

#pragma once
#include 
#include 
#include 
#include /******************************************************************************/
/**********************ufgnix0802:单例宏定义(线程安全)*************************/
/******************************************************************************/#define SINGLETON_CLASS_DEFAULT(Class)                                          \private:                                                                    \Class() {}                                                              \~Class() {}                                                             \Class(Class &other) {}                                                  \Class(const Class &other) {}                                            \Class& operator=(Class &other) {}                                       \Class& operator=(const Class &other) {}                                 \
#define SINGLETON_CLASS_FUNC_DECL(Class)                                        \public:                                                                     \static Class& Ins();                                                    \private:                                                                    \static void InitSingleton();                                            \\static void Release();                                                  \\SINGLETON_CLASS_DEFAULT(Class)                                          \
private:                                                                        \static std::once_flag m_singletonFlag;                                      \static Class* m_ins;/* https://liam.page/2020/10/27/implement-a-singleton-class-template-in-cxx/ */                         
/* https://liam.page/2017/01/17/layers-and-operation-system/#CPU-%E5%8A%A8%E6%80%81%E8%B0%83%E5%BA%A6 */#define SINGLETON_CLASS_FUNC_IMPL(Class)                                        \Class& Class::Ins() {                                                       \/* 使用双重检查,外层检查是为了避免锁住过大的面积,从而导致锁的竞争特别频繁;*/\/* 内层检查是为了确保只在其它线程没有抢占锁完成初始化工作而设计。*/           \/* 这种做法在Java下是正确的,但是在C++下则没有保证。*/                      \/* std::once_flag 和 std::call_once:它们内部利用互斥量和条件变量组合,*/   \/* 实现这样的语义。值得一提的是,如果执行过程中抛出异常,标准库的设施不认为 */ \/* 这是一次「成功的执行」。于是其他线程可以继续抢占锁来执行函数。 */          \/* std:call_once确保函数或代码片段在多线程环境下,只需要执行一次。 */        \std::call_once(m_singletonFlag, &Class::InitSingleton);                 \assert(m_ins != NULL);                                                  \return *m_ins;                                                          \}                                                                           \\void Class::InitSingleton() {                                               \m_ins = new Class;                                                      \if (m_ins) {                                                            \/* C 库函数 int atexit(void (*func)(void)) 当程序正常终止时,调用指定的*/  \/* 函数func。您可以在任何地方注册你的终止函数,*/                           \/* 但它会在程序终止的时候被调用。*/                                        \::atexit(Release);                                              \}                                                                       \}                                                                           \\void Class::Release() {                                                     \if (m_ins) {                                                           \delete m_ins;                                                     \m_ins = NULL;                                                     \}                                                                      \}                                                                   #define SINGLETON_CLASS_VARIABLE_IMPL(Class)                                    \std::once_flag Class::m_singletonFlag;                                  \Class* Class::m_ins = NULL;#define SINGLETON_CLASS_IMPL(Class)                                             \SINGLETON_CLASS_VARIABLE_IMPL(Class)                                    \SINGLETON_CLASS_FUNC_IMPL(Class)                                        

使用方式

  注意,如果我们的单例类对象在.hpp文件中那么可能出现重定义的问题,博主设计的单例模板,只适用于.h和.cpp,即声明和定义分开单例类对象。

Aclass.h

#include "ISingleton.hpp"class Aclass {//声明SINGLETON_CLASS_FUNC_DECL(Aclass)public:int a;};

Aclass.cpp

#include "Aclass.h"//定义
SINGLETON_CLASS_IMPL(Aclass);

main.c

#include "Aclass.h"
int main() {//Aclass a;  errAclass::Ins().a = 5;std::cout << Aclass::Ins().a << std::endl;return 0;
}

  运行结果:
效果图

相关内容

热门资讯

美国2年期国债收益率上涨15个... 原标题:美国2年期国债收益率上涨15个基点 美国2年期国债收益率上涨15个基...
汽车油箱结构是什么(汽车油箱结... 本篇文章极速百科给大家谈谈汽车油箱结构是什么,以及汽车油箱结构原理图解对应的知识点,希望对各位有所帮...
嵌入式 ADC使用手册完整版 ... 嵌入式 ADC使用手册完整版 (188977万字)💜&#...
重大消息战皇大厅开挂是真的吗... 您好:战皇大厅这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...
盘点十款牵手跑胡子为什么一直... 您好:牵手跑胡子这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游...
senator香烟多少一盒(s... 今天给各位分享senator香烟多少一盒的知识,其中也会对sevebstars香烟进行解释,如果能碰...
终于懂了新荣耀斗牛真的有挂吗... 您好:新荣耀斗牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信8435338】很多玩家在这款游戏...
盘点十款明星麻将到底有没有挂... 您好:明星麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5848499】很多玩家在这款游戏...
总结文章“新道游棋牌有透视挂吗... 您好:新道游棋牌这款游戏可以开挂,确实是有挂的,需要了解加客服微信【7682267】很多玩家在这款游...
终于懂了手机麻将到底有没有挂... 您好:手机麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...