一行宏定义使一个类变为单例类

一、介绍:

编写一个单例框架,使得最终通过一行宏定义,将一个类变为单例类。减少客户侧定义单例类时编写重复代码。

二、代码:

2.1、单例框架代码:

// Singleton.h
// description: 单例框架模板
// author: XXX
// date: XXX

#ifndef INCLUDE_TOOLS_SINGLETON
#define INCLUDE_TOOLS_SINGLETON

#include <iostream>
#include <atomic>
#include <utility>

template<typename class_name>
class Singleton
{
public:
    using singleton_ptr = class_name*;

public:
    template <typename... Args>
    static singleton_ptr get_instance(Args &&... args)
    {
        if (!get_instance_ptr().load()) {  // 判断是否第一次调用
            get_instance_ptr().exchange(new class_name(std::forward<Args>(args)...));
            std::cout << "create this class " << get_instance_ptr().load() << std::endl;
        }
        std::cout << "already created this class " << get_instance_ptr().load() << std::endl;
        return get_instance_ptr().load();
    }

    static void destory()
    {
        auto ptr = get_instance_ptr().exchange(nullptr);
        delete ptr;
    }

private:
    static std::atomic<singleton_ptr>& get_instance_ptr()
    {
        static std::atomic<singleton_ptr> instance_;
        return instance_;
    }

    Singleton() = delete;
    ~Singleton() {}

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

#define SINGLETON_CLASS(class_name) \
public: \
    friend class Singleton<class_name>; \
    template <typename... Args> \
    static class_name* get_instance(Args &&... args) \
    { \
        return Singleton<class_name>::get_instance(std::forward<Args>(args)...); \
    } \
    static void destory() \
    { \
        Singleton<class_name>::destory(); \
    }
#endif

2.2、客户侧使用代码:

// 客户侧使用代码
#include "Singleton.h"

// 单例测试类A
class A
{
    SINGLETON_CLASS(A);

public:
    void print_a_b() { std::cout << a << b << std::endl;}

private:
    A(int x, int y) : a(x), b(y) {}

private:
    int a;
    int b;
};

// 单例测试类B
class B
{
    SINGLETON_CLASS(B);

public:
    void print_empty() { std::cout << "empty"<< std::endl;}

private:
    B() = default;
};

2.3、使用案例:

void test_singleton()
{
    A::get_instance(2, 3)->print_a_b();
    std::cout << "--------Split line-------------" << std::endl;
    B::get_instance()->print_empty();
    A::get_instance(2, 3)->print_a_b();
}

源码链接: github地址

三、总结:

1、将目标类声明为单例时,在类声明中加入SINGLETON_CLASS(class_name);即可。
2、使用目标单例时,调用class_name::get_instance()->即可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值