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

单例模式在 C++ 中的核心目标是:确保一个类只有一个实例,并提供全局访问点。关键难点在于线程安全、懒加载、析构时机和模板复用。下面从实用角度讲清几种主流实现方式及其适用场景。
C++11 标准保证了 局部静态变量的初始化是线程安全的,这是最推荐的现代写法,无需手动加锁,也天然支持懒加载:
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // 仅首次调用时构造,且线程安全
return instance;
}
<pre class="brush:php;toolbar:false;">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<std::mutex> lock(mutex_);
if (!instance) {
instance = new ConfigManager("config.json");
}
}
return *instance;
}
<pre class="brush:php;toolbar:false;">static void destroy() {
std::lock_guard<std::mutex> 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)风格基类:
template<typename T>
class SingletonBase {
protected:
SingletonBase() = default;
~SingletonBase() = default;
<p>public:
SingletonBase(const SingletonBase&) = delete;
SingletonBase& operator=(const SingletonBase&) = delete;</p><pre class="brush:php;toolbar:false;">static T& getInstance() {
static T instance;
return instance;
}};
立即学习“C++免费学习笔记(深入)”;
// 使用方式:
class Logger : public SingletonBase
✅ 优点:一行继承即获得单例能力,类型安全,无宏污染
⚠️ 注意:子类构造/析构函数需设为 protected,并通过 friend 放行基类访问;不适用于需要参数构造的场景(可扩展为带参数的变体)。
单例不是银弹——滥用会导致隐式依赖、难以测试、妨碍模块解耦。真正需要全局唯一状态时再用,优先考虑依赖注入或作用域明确的局部对象。
以上就是c++++如何实现单例模式 设计模式在c++中的应用【进阶必看】的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号