设计模式—单例模式深度分析与实现【c++与golang】

文章详细介绍了单例模式的原理,包括保证类只有一个实例和提供全局访问点。讨论了C++中实现单例的三种方法:加锁的懒汉式、局部变量的懒汉式和饿汉式,分析了各自的优缺点。同时,文章还探讨了Go语言中实现单例模式的饿汉式和利用`sync.Once`保证线程安全的懒汉式方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

最近在写项目的时候用到单例模式,之前只是简单的使用。在 C++ 中,实现单例模式的方法有多种,今天对单例模式做一个深度的总结与对比,将介绍单例模式的原理、实现方法以及各种方法的优缺点。

一、单例模式的原理

单例模式是一种常用的设计模式,用于保证一个类只有一个实例存在,并提供一个全局访问点。
单例模式的核心思想是让一个类只能创建一个实例,并提供一个全局访问点,以便在程序中任何地方都可以访问该实例。在 C++ 中,可以通过以下步骤来实现单例模式:定义静态成员变量的目的是为了保存单例对象,使得工厂方法能够返回这个唯一的实例。而将默认构造函数设为私有,则是为了防止外部程序随意创建单例对象
将类的构造函数设为私有,禁止外部创建实例。
定义一个静态成员变量,用于保存单例对象。
构造一个全局的工厂方法,用于获取单例对象。

简单例子

class Singleton {
   
   
public:
    static Singleton& getInstance() {
   
   
        static Singleton instance;  // 创建静态变量保存唯一实例
        return instance;
    }

    void printMessage() {
   
   
        std::cout << "Hello, World!" << std::endl;
    }

private:
    Singleton() {
   
   }  // 将构造函数设为私有,禁止外部创建实例
    Singleton(const Singleton&) = delete;  // 禁止拷贝构造
    Singleton& operator=(const Singleton&) = delete;  // 禁止赋值操作
};

int main() {
   
   
    Singleton& instance1 = Singleton::getInstance();
    Singleton& instance2 = Singleton::getInstance();
    std::cout << std::boolalpha << (&instance1 == &instance2) << std::endl;
    instance1.printMessage();  // 输出 "Hello, World!"
    instance2.printMessage();  // 输出 "Hello, World!"
    return 0;
}

在上面的例子中,Singleton 类的构造函数被设为私有,禁止外部创建实例。getInstance() 函数返回一个静态的 Singleton 类型变量,用于保存类的唯一实例。由于该变量是静态的,因此只会在程序第一次调用 getInstance() 函数时被创建。

在 main() 函数中,我们分别通过 Singleton::getInstance() 函数获取两个 Singleton 类型的实例 instance1 和 instance2。由于 Singleton 类只有一个实例,因此我们可以使用地址比较运算符 & 来验证它们是否是同一个实例。最后,我们通过 instance1 和 instance2 分别调用 Singleton 类的成员函数 printMessage(),输出 “Hello, World!”。

二、实现单例模式的几种方法

单例模式有两种类型:
懒汉式:在真正需要使用对象时才去创建该单例类对象
饿汉式:在类加载时已经创建好该单例对象,等待被程序使用

1.加锁的懒汉式

加锁的懒汉式是指在第一次调用 getInstance() 函数时,通过加锁的方式来保证线程安全。如果实例还没有被创建,则创建实例并返回实例的指针;如果实例已经被创建,则直接返回实例的指针。以下是一个加锁的懒汉式的实现:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值