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

 更新时间:2023年02月10日 14:23:43   作者:ufgnix0802  
在我们日常开发中,无可避免需要使用单例模式进行设计类对象。这篇文章主要介绍了如何使用宏函数实现单例模板,感兴趣的小伙伴可以了解一下

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

ISingleton.hpp

#pragma once
#include <stdlib.h>
#include <assert.h>
#include <thread>
#include <mutex>


/******************************************************************************/
/**********************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;  err
    Aclass::Ins().a = 5;
    std::cout << Aclass::Ins().a << std::endl;
    return 0;
}

运行结果:

到此这篇关于C++使用宏函数实现单例模板详解的文章就介绍到这了,更多相关C++宏函数实现单例模板内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 利用C语言实现三子棋(井字棋)小游戏

    利用C语言实现三子棋(井字棋)小游戏

    这篇文章主要为大家详细介绍了利用C语言实现三子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • 基于Matlab实现鲸鱼优化算法的示例代码

    基于Matlab实现鲸鱼优化算法的示例代码

    鲸鱼优化算法(WOA)是澳大利亚学者Mirjaili等于2016年提出的群体智能优化算法,根据座头鲸的捕猎行为实现优化搜索的目的。本文将利用Matlab实现这一算法,需要的可以参考一下
    2022-04-04
  • Qt QCompleter自动补全的实现

    Qt QCompleter自动补全的实现

    本文主要介绍了Qt QCompleter自动补全的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • C 语言简单加减乘除运算

    C 语言简单加减乘除运算

    本篇文章主要介绍了C语言的基本运算方法,这里对加法,减法,乘法,除法,求余数,做了详细讲解,有需要的朋友可以参考下
    2016-07-07
  • 深入理解C++编程中的局部变量和全局变量

    深入理解C++编程中的局部变量和全局变量

    这篇文章主要介绍了深入理解C++编程中的局部变量和全局变量,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C++动态数组类的封装实例

    C++动态数组类的封装实例

    这篇文章主要介绍了C++动态数组类的封装,很重要的概念,需要的朋友可以参考下
    2014-08-08
  • 解决C语言中使用scanf连续输入两个字符类型的问题

    解决C语言中使用scanf连续输入两个字符类型的问题

    这篇文章主要介绍了解决C语言中使用scanf连续输入两个字符类型的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • C语言中#if的使用详解

    C语言中#if的使用详解

    #if和#endif是一组同时使用的,叫做条件编译指令。#if与#define、#include等指令一样是由预处理器这个强大的工具处理的,预处理器可以在编译前处理c程序,这篇文章主要介绍了C语言中#if的使用,需要的朋友可以参考下
    2022-11-11
  • C/C++中for语句循环用法以及练习举例

    C/C++中for语句循环用法以及练习举例

    for语句是一种循环语句,它是对while语句的推广,下面这篇文章主要给大家介绍了关于C/C++中for语句循环用法以及练习举例的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • 一起来了解c语言的str函数

    一起来了解c语言的str函数

    这篇文章主要为大家详细介绍了c语言的str函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02

最新评论