c++如何实现单例模式 设计模式在c++中的应用【进阶必看】

C++单例模式推荐使用C++11局部静态变量实现,线程安全且懒加载;需传参或控制销毁时机时用指针+双重检查锁;模板化CRTP基类可复用,但不支持参数构造;避免老式懒汉、饿汉及宏实现。

c++如何实现单例模式 设计模式在c++中的应用【进阶必看】

单例模式在 C++ 中的核心目标是:确保一个类只有一个实例,并提供全局访问点。关键难点在于线程安全、懒加载、析构时机和模板复用。下面从实用角度讲清几种主流实现方式及其适用场景。

最简线程安全的懒汉式(C++11 及以后)

C++11 标准保证了 局部静态变量的初始化是线程安全的,这是最推荐的现代写法,无需手动加锁,也天然支持懒加载:

class Singleton {public:    static Singleton& getInstance() {        static Singleton instance; // 仅首次调用时构造,且线程安全        return instance;    }
Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;

private:Singleton() = default; // 构造函数私有~Singleton() = default; // 析构函数私有(可选,若需控制销毁时机则留 public)};

✅ 优点:简洁、安全、高效、自动管理生命周期
⚠️ 注意:析构发生在 main() 返回后、全局对象销毁阶段;若其他静态对象依赖该单例,可能引发“静态析构顺序问题”。

带显式初始化控制的单例(适用于需延迟构造参数或避免静态析构风险)

当单例构造需要运行时参数,或你希望完全掌控创建/销毁时机(比如游戏引擎中模块按需启停),可用指针 + 懒加载 + 手动管理:

class ConfigManager {public:    static ConfigManager& getInstance() {        if (!instance) {            std::lock_guard lock(mutex_);            if (!instance) {                instance = new ConfigManager("config.json");            }        }        return *instance;    }
static void destroy() {    std::lock_guard lock(mutex_);    delete instance;    instance = nullptr;}

private:ConfigManager(const std::string& cfgPath) { / 加载配置 / }~ConfigManager() = default;

static ConfigManager* instance;static std::mutex mutex_;

};

立即学习“C++免费学习笔记(深入)”;

ConfigManager* ConfigManager::instance = nullptr;std::mutex ConfigManager::mutex_;

✅ 优点:可传参、可主动销毁、规避静态析构顺序问题
⚠️ 注意:必须确保 destroy() 在所有使用方之后调用;多线程下双重检查锁(Double-Checked Locking)需配合 std::atomic 或确保编译器不重排(C++11 起该写法已安全)。

模板化通用单例基类(减少重复代码)

为多个类快速添加单例能力,可设计 CRTP(Curiously Recurring Template Pattern)风格基类:

templateclass SingletonBase {protected:    SingletonBase() = default;    ~SingletonBase() = default;

public:SingletonBase(const SingletonBase&) = delete;SingletonBase& operator=(const SingletonBase&) = delete;

static T& getInstance() {    static T instance;    return instance;}

};

立即学习“C++免费学习笔记(深入)”;

// 使用方式:class Logger : public SingletonBase {friend class SingletonBase;Logger() = default;public:void log(const std::string& msg) { / ... / }};

✅ 优点:一行继承即获得单例能力,类型安全,无宏污染
⚠️ 注意:子类构造/析构函数需设为 protected,并通过 friend 放行基类访问;不适用于需要参数构造的场景(可扩展为带参数的变体)。

不推荐但需了解的写法

老式懒汉式(全局锁 + 静态指针):C++03 常见,但易出竞态、易忘 delete、易内存泄漏;C++11 后已无必要。饿汉式(全局静态对象):启动即构造,线程安全但不懒加载,且无法控制构造顺序,还可能触发“静态初始化顺序 fiasco”。宏实现单例:破坏封装、调试困难、模板不友好,现代 C++ 应避免。

单例不是银弹——滥用会导致隐式依赖、难以测试、妨碍模块解耦。真正需要全局唯一状态时再用,优先考虑依赖注入或作用域明确的局部对象。

以上就是c++++如何实现单例模式 设计模式在c++中的应用【进阶必看】的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1489737.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
c++中的alignas和alignof关键字_c++内存对齐控制详解
上一篇 2025年12月19日 12:39:43
C++如何实现高性能日志系统_探讨C++异步日志的设计与实现
下一篇 2025年12月19日 12:40:00

相关推荐

发表回复

登录后才能评论
关注微信