You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何理解MAKE_SINGLETON宏的最终输出?是否调用了MAKE_SINGLETON_2?

MAKE_SINGLETON系列宏解析与展开说明

一、典型MAKE_SINGLETON系列宏定义

这类宏的核心是自动生成单例模式的样板代码,常见的实现会采用分层设计,比如:

// 对外简化接口的宏,直接转发到底层宏
#define MAKE_SINGLETON(CLASS) \
    MAKE_SINGLETON_2(CLASS, CLASS)

// 底层扩展宏,支持自定义返回类型
#define MAKE_SINGLETON_2(CLASS, INSTANCE_TYPE) \
private: \
    CLASS() = default; \
    ~CLASS() = default; \
    CLASS(const CLASS&) = delete; \
    CLASS& operator=(const CLASS&) = delete; \
public: \
    static INSTANCE_TYPE& GetInstance() { \
        static INSTANCE_TYPE instance; \
        return instance; \
    }

二、CConnManager类中的使用与代码展开

假设你在类中的使用代码如下:

class CConnManager {
    MAKE_SINGLETON(CConnManager)
    // 其他业务成员定义
};

经过预处理器展开后,代码会被替换为:

class CConnManager {
private:
    CConnManager() = default;
    ~CConnManager() = default;
    CConnManager(const CConnManager&) = delete;
    CConnManager& operator=(const CConnManager&) = delete;
public:
    static CConnManager& GetInstance() {
        static CConnManager instance;
        return instance;
    }
    // 其他业务成员定义
};

三、是否最终调用MAKE_SINGLETON_2?

如果你的MAKE_SINGLETON宏是类似上述的转发式定义(即直接将参数传递给MAKE_SINGLETON_2),那么必然会调用MAKE_SINGLETON_2。

MAKE_SINGLETON_2的设计初衷是为了扩展灵活性:比如当单例类继承自某个接口时,可以让GetInstance返回接口类型的引用,适配面向接口编程的场景,示例如下:

class IConnManager {
    // 接口方法声明
};

class CConnManager : public IConnManager {
    MAKE_SINGLETON_2(CConnManager, IConnManager)
    // 接口方法实现
};

// 此时调用GetInstance返回的是IConnManager&类型
IConnManager& manager = CConnManager::GetInstance();

四、核心特性说明

  • 生成的是Meyers单例,依赖C++11及以后标准中静态局部变量的线程安全初始化特性,无需额外加锁。
  • 宏自动禁用了拷贝构造和赋值运算符,从语法层面禁止类的多实例化。
  • 分层的宏设计(MAKE_SINGLETON + MAKE_SINGLETON_2)兼顾了易用性和扩展性:普通场景用MAKE_SINGLETON简化调用,特殊场景用MAKE_SINGLETON_2自定义返回类型。

内容的提问来源于stack exchange,提问作者user24501612

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:55:23