欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > C++单例模式

C++单例模式

2025/11/6 6:18:13 来源:https://blog.csdn.net/qq_45993770/article/details/142877980  浏览:    关键词:C++单例模式

C++ 中的单例模式

单例模式(Singleton Pattern)是一种常用的设计模式,确保一个类在应用程序的生命周期内只有一个实例,并提供全局访问点。它适用于需要在整个系统中共享资源或协调行为的场景,例如日志记录、配置管理器、线程池等。


单例模式的关键特性

  • 唯一实例:类只创建一个实例,所有对该类的调用都返回相同的实例。
  • 全局访问点:提供一个全局访问点,方便其他对象获取该实例。
  • 受控实例化:类自身控制实例的创建过程,防止外部直接创建对象。

在 C++ 中实现单例模式

下面介绍几种在 C++ 中实现单例模式的方法,包括线程安全的实现和注意事项。


1. 基本单例实现(懒汉式,C++11 及以上)
class Singleton {
private:// 私有构造函数,防止外部实例化Singleton() {// 初始化代码}// 删除拷贝构造和赋值运算符,防止复制Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;public:// 获取实例的静态方法static Singleton& getInstance() {static Singleton instance; // C++11 保证线程安全的初始化return instance;}// 公共方法void someMethod() {// 方法实现}
};

使用方法:

Singleton& singleton = Singleton::getInstance();
singleton.someMethod();

说明:

  • 私有构造函数:防止外部通过 new 操作符创建对象。
  • 删除拷贝构造和赋值运算符:防止复制或赋值实例。
  • 静态局部变量getInstance() 中的静态局部变量 instance,在第一次调用时创建,且 C++11 保证其线程安全。

2. 懒汉式单例(手动控制线程安全)

如果使用的是 C++11 之前的标准,或者需要更明确地控制线程安全:

#include <mutex>class Singleton {
private:static Singleton* instance;static std::mutex mtx;Singleton() {// 初始化代码}public:static Singleton* getInstance() {if (instance == nullptr) {std::lock_guard<std::mutex> lock(mtx);if (instance == nullptr) {instance = new Singleton();}}return instance;}// 公共方法void someMethod() {// 方法实现}
};// 静态成员变量初始化
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;

说明:

  • 双重检查锁定:第一次检查 instance 是否为 nullptr,避免不必要的加锁。加锁后再次检查,确保线程安全。
  • 手动内存管理:需要注意实例的释放,可以在程序结束时手动删除,或者使用智能指针。

3. 使用 std::call_once 实现线程安全单例

C++11 提供了 std::call_oncestd::once_flag,可以更简单地实现线程安全的单例:

#include <mutex>class Singleton {
private:static Singleton* instance;static std::once_flag flag;Singleton() {// 初始化代码}public:static Singleton* getInstance() {std::call_once(flag, []() {instance = new Singleton();});return instance;}// 公共方法void someMethod() {// 方法实现}
};// 静态成员变量初始化
Singleton* Singleton::instance = nullptr;
std::once_flag Singleton::flag;

说明:

  • std::call_once:确保传递的初始化函数只调用一次,线程安全且高效。

4. 饿汉式单例(程序启动时创建实例)
class Singleton {
private:static Singleton instance;Singleton() {// 初始化代码}public:static Singleton& getInstance() {return instance;}// 公共方法void someMethod() {// 方法实现}
};// 静态成员变量初始化
Singleton Singleton::instance;

说明:

  • 实例在程序启动时创建:适用于实例创建开销小,且一定会使用的情况。
  • 线程安全:由于实例在程序开始时创建,避免了多线程访问时的同步问题。

注意事项

  • 析构问题:如果单例对象在程序结束时需要释放资源,需要注意析构函数的调用时机,可能涉及到静态对象的销毁顺序问题。
  • 多线程环境:在多线程环境下,必须确保单例的实例化过程是线程安全的,推荐使用 C++11 提供的线程库。
  • 拷贝控制:必须删除拷贝构造函数和赋值运算符,防止通过复制方式创建新实例。
  • 谨慎使用单例:单例模式可能导致代码的高耦合性,过度使用会影响代码的可测试性和可维护性,应根据实际需求慎重考虑。

完整示例

#include <iostream>
#include <mutex>class Logger {
private:static Logger* instance;static std::mutex mtx;Logger() {// 私有构造函数}// 禁止拷贝和赋值Logger(const Logger&) = delete;Logger& operator=(const Logger&) = delete;public:static Logger* getInstance() {std::lock_guard<std::mutex> lock(mtx);if (instance == nullptr) {instance = new Logger();}return instance;}void log(const std::string& message) {// 日志记录实现std::cout << "Log: " << message << std::endl;}
};// 静态成员变量初始化
Logger* Logger::instance = nullptr;
std::mutex Logger::mtx;// 使用示例
int main() {Logger::getInstance()->log("This is a singleton pattern example.");return 0;
}

总结

单例模式在需要全局共享资源的情况下非常有用。使用 C++11 及以上标准,可以利用语言特性简单、高效地实现线程安全的单例模式。需要注意的是,单例模式也有其缺点,可能引入全局状态,影响代码的可测试性和可维护性。因此,在设计系统时,应权衡利弊,合理使用单例模式。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词