C++如何实现单例模式的饿汉式与懒汉式

来源:AI编程作者:半糖头衔:草根站长
导读:本期聚焦于小伙伴创作的《C++如何实现单例模式的饿汉式与懒汉式》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++如何实现单例模式的饿汉式与懒汉式》有用,将其分享出去将是对创作者最好的鼓励。

单例模式是面向对象设计中常用的创建型模式,目的是确保某个类在全局范围内只有一个实例,并且提供统一的访问入口。在C++中,饿汉式和懒汉式是两种最主流的实现方式,二者的核心区别在于实例的初始化时机不同,适用的场景也有明显差异。

C++如何实现单例模式的饿汉式与懒汉式

单例模式的核心约束

无论采用哪种实现方式,单例模式都需要满足三个基本条件:

  • 构造函数私有化,禁止外部直接通过new关键字创建实例
  • 类内部维护一个自身的静态实例指针或引用
  • 提供一个公开的静态方法,用于获取唯一的实例

饿汉式单例实现

饿汉式的核心特点是实例在程序启动时就已经完成初始化,不需要考虑多线程竞争的问题,实现逻辑相对简单。

基础实现代码

#include <iostream>

class HungrySingleton {
private:
    // 私有构造函数,禁止外部实例化
    HungrySingleton() {
        std::cout << "饿汉式单例实例创建" << std::endl;
    }

    // 静态实例,程序启动时直接初始化
    static HungrySingleton instance;

public:
    // 禁止拷贝构造函数和赋值运算符
    HungrySingleton(const HungrySingleton&) = delete;
    HungrySingleton& operator=(const HungrySingleton&) = delete;

    // 获取单例实例的静态方法
    static HungrySingleton& getInstance() {
        return instance;
    }

    // 示例方法
    void doSomething() {
        std::cout << "饿汉式单例执行操作" << std::endl;
    }
};

// 类外初始化静态实例
HungrySingleton HungrySingleton::instance;

int main() {
    // 获取单例实例并调用方法
    HungrySingleton::getInstance().doSomething();
    return 0;
}

饿汉式的优缺点

饿汉式的优势是实现简单,不需要处理线程同步问题,因为静态实例的初始化在程序进入main函数之前就已经完成,多线程环境下不会出现重复创建的问题。缺点是如果单例类的初始化成本较高,会提前占用系统资源,即使后续不会用到这个实例,资源也无法释放。

懒汉式单例实现

懒汉式的实例只有在第一次被调用时才会创建,能够避免不必要的资源占用,但需要考虑多线程环境下的线程安全问题。

线程不安全的懒汉式实现

#include <iostream>

class LazySingleton {
private:
    // 私有构造函数
    LazySingleton() {
        std::cout << "懒汉式单例实例创建" << std::endl;
    }

    // 静态实例指针,初始化为nullptr
    static LazySingleton* instance;

public:
    // 禁止拷贝和赋值
    LazySingleton(const LazySingleton&) = delete;
    LazySingleton& operator=(const LazySingleton&) = delete;

    // 获取单例实例的方法
    static LazySingleton* getInstance() {
        if (instance == nullptr) {
            instance = new LazySingleton();
        }
        return instance;
    }

    void doSomething() {
        std::cout << "懒汉式单例执行操作" << std::endl;
    }
};

// 初始化静态指针
LazySingleton* LazySingleton::instance = nullptr;

int main() {
    LazySingleton::getInstance()->doSomething();
    return 0;
}

这种实现方式在单线程环境下可以正常工作,但多线程同时调用getInstance方法时,可能会出现多个线程同时判断instance为nullptr,从而创建多个实例,违反单例的原则。

线程安全的懒汉式实现(双重检查锁)

#include <iostream>
#include <mutex>

class SafeLazySingleton {
private:
    SafeLazySingleton() {
        std::cout << "线程安全懒汉式单例实例创建" << std::endl;
    }

    static SafeLazySingleton* instance;
    static std::mutex mtx; // 互斥锁,用于线程同步

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

    static SafeLazySingleton* getInstance() {
        // 第一次检查,避免已经初始化后还要加锁的性能损耗
        if (instance == nullptr) {
            std::lock_guard<std::mutex> lock(mtx);
            // 第二次检查,防止多个线程同时通过第一次检查后重复创建
            if (instance == nullptr) {
                instance = new SafeLazySingleton();
            }
        }
        return instance;
    }

    void doSomething() {
        std::cout << "线程安全懒汉式单例执行操作" << std::endl;
    }
};

SafeLazySingleton* SafeLazySingleton::instance = nullptr;
std::mutex SafeLazySingleton::mtx;

int main() {
    SafeLazySingleton::getInstance()->doSomething();
    return 0;
}

基于局部静态变量的懒汉式实现

C++11之后,局部静态变量的初始化是线程安全的,因此可以用更简洁的方式实现线程安全的懒汉式单例:

#include <iostream>

class LocalStaticLazySingleton {
private:
    LocalStaticLazySingleton() {
        std::cout << "局部静态变量懒汉式单例实例创建" << std::endl;
    }

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

    static LocalStaticLazySingleton& getInstance() {
        // 局部静态变量,第一次调用时初始化,C++11保证线程安全
        static LocalStaticLazySingleton instance;
        return instance;
    }

    void doSomething() {
        std::cout << "局部静态变量懒汉式单例执行操作" << std::endl;
    }
};

int main() {
    LocalStaticLazySingleton::getInstance().doSomething();
    return 0;
}

两种实现方式的对比

对比维度饿汉式懒汉式
初始化时机程序启动时首次调用getInstance时
线程安全天然线程安全需要额外处理才线程安全
资源占用提前占用资源,可能浪费按需分配,更节省资源
实现复杂度简单需要考虑线程同步,复杂度稍高
适用场景实例初始化成本低、大概率会被使用实例初始化成本高、可能不会被使用

实现注意事项

  • 单例类的构造函数一定要私有化,否则外部可以直接创建实例,破坏单例约束
  • 一定要禁用拷贝构造函数和赋值运算符,避免通过拷贝方式创建新的实例
  • 如果单例需要管理资源,还需要考虑实例的销毁逻辑,避免内存泄漏
  • C++11及以上版本优先使用局部静态变量的懒汉式实现,代码简洁且线程安全有保障

C++单例模式饿汉式懒汉式设计模式修改时间:2026-06-15 22:21:20

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。