0

0

C++如何实现单例模式保证全局唯一对象

P粉602998670

P粉602998670

发布时间:2025-09-12 09:54:02

|

661人浏览过

|

来源于php中文网

原创

单例模式通过私有构造函数、静态实例和全局访问点确保类唯一实例,常用静态初始化或双重检查锁实现线程安全,适用于日志、配置管理等场景,应避免滥用以降低耦合。

c++如何实现单例模式保证全局唯一对象

单例模式的核心在于确保一个类只有一个实例,并提供一个全局访问点。C++实现单例的关键在于控制对象的创建和访问。

解决方案

  1. 私有化构造函数和拷贝构造函数: 防止外部直接创建和复制对象。
  2. 静态成员变量: 用于存储唯一的实例。
  3. 静态成员函数: 提供全局访问点,负责创建和返回实例。
  4. 线程安全: 在高并发环境下,需要考虑线程安全问题。

下面是一个简单的C++单例模式实现:

#include 
#include 

class Singleton {
private:
    Singleton() {
        std::cout << "Singleton created" << std::endl;
    }
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    static Singleton* instance;
    static std::mutex mutex;

public:
    static Singleton* getInstance() {
        std::lock_guard lock(mutex);
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }

    void doSomething() {
        std::cout << "Singleton is doing something" << std::endl;
    }

    ~Singleton() {
        std::cout << "Singleton destroyed" << std::endl;
    }

    //防止内存泄漏
    class Garbo {
    public:
        ~Garbo(){
            if (Singleton::instance != nullptr) {
                delete Singleton::instance;
                Singleton::instance = nullptr;
            }
        }
    };

    static Garbo garbo;
};

Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex;
Singleton::Garbo Singleton::garbo;


int main() {
    Singleton* instance1 = Singleton::getInstance();
    instance1->doSomething();

    Singleton* instance2 = Singleton::getInstance();
    instance2->doSomething();

    if (instance1 == instance2) {
        std::cout << "Both instances are the same" << std::endl;
    }

    //不需要手动释放,程序结束时会自动释放
    return 0;
}

这段代码首先私有化了构造函数和拷贝构造函数,阻止了外部直接实例化和复制

Singleton
对象。
getInstance
方法使用了双重检查锁(double-checked locking)模式,在多线程环境下确保只有一个实例被创建。
Garbo
类的静态成员变量在程序结束时会自动调用析构函数,从而释放单例对象的内存,避免内存泄漏。

如何保证单例模式的线程安全?

在高并发环境下,多个线程可能同时调用

getInstance
方法,导致创建多个实例。为了保证线程安全,可以使用互斥锁(mutex)来同步线程访问。

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

双重检查锁(Double-Checked Locking)是一种常用的线程安全单例模式实现方式,但需要注意内存模型问题。在C++11之后,由于内存模型的改进,双重检查锁可以正确工作。

除了互斥锁,还可以使用静态初始化来保证线程安全。静态变量的初始化在C++标准中是线程安全的,因此可以利用这一特性来简化单例模式的实现:

有道智云AI开放平台
有道智云AI开放平台

有道智云AI开放平台

下载
class Singleton {
private:
    Singleton() {
        std::cout << "Singleton created" << std::endl;
    }
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

public:
    static Singleton& getInstance() {
        static Singleton instance; // 静态初始化,线程安全
        return instance;
    }

    void doSomething() {
        std::cout << "Singleton is doing something" << std::endl;
    }

    ~Singleton() {
        std::cout << "Singleton destroyed" << std::endl;
    }
};

int main() {
    Singleton& instance1 = Singleton::getInstance();
    instance1.doSomething();

    Singleton& instance2 = Singleton::getInstance();
    instance2.doSomething();

    if (&instance1 == &instance2) {
        std::cout << "Both instances are the same" << std::endl;
    }

    return 0;
}

这种方式更加简洁,并且依赖于C++标准的线程安全保证。

单例模式有哪些常见的应用场景?

单例模式常用于以下场景:

  • 日志记录器: 系统中只有一个日志记录器实例,负责记录所有日志信息。
  • 配置管理器: 应用程序只需要一个配置管理器实例,负责读取和管理配置信息。
  • 数据库连接池: 只有一个数据库连接池实例,负责管理数据库连接。
  • 任务管理器: 系统中只需要一个任务管理器来管理任务队列。
  • 缓存管理器: 应用程序共享一个缓存管理器实例,负责缓存数据。

在这些场景中,使用单例模式可以确保全局只有一个实例,避免资源浪费和数据不一致的问题。

如何避免单例模式的滥用?

单例模式虽然有用,但过度使用会导致代码的耦合度增加,测试难度加大。因此,需要谨慎使用单例模式,避免滥用。

以下是一些建议:

  • 只在真正需要全局唯一实例的场景下使用单例模式。 如果一个类可以有多个实例,则不应该使用单例模式。
  • 考虑使用依赖注入(Dependency Injection)来替代单例模式。 依赖注入可以降低代码的耦合度,提高代码的可测试性。
  • 避免在单例类中存储可变状态。 如果单例类中存储了可变状态,则需要考虑线程安全问题,并且容易导致代码的复杂性增加。
  • 尽量使用静态初始化方式实现单例模式。 静态初始化方式更加简洁,并且可以保证线程安全。

总之,单例模式是一种有用的设计模式,但需要谨慎使用,避免滥用。选择合适的设计模式,才能编写出高质量的代码。

相关专题

更多
c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

48

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

95

2025.10.23

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

471

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

107

2025.12.24

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

332

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2068

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

346

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

251

2023.09.05

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.7万人学习

C 教程
C 教程

共75课时 | 3.8万人学习

C++教程
C++教程

共115课时 | 10.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号