设计模式之单例模式

本文介绍了C++中如何通过模板类实现线程安全的懒汉式单例模式,详细展示了单例模式的作用,如节约资源和确保唯一实例。示例代码中展示了如何在类外使用模板创建单例,并通过友元类访问其私有构造函数,以防止外部直接创建对象。最后,给出了一个简单的示例应用,展示了如何调用单例模式实现的类方法。

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

单例模式

单例模式作用

1.只能创建一个对象,节约资源。
2.保证他是唯一的实例,且线程安全。

懒汉式

线程安全的懒汉式-单例模板

#include <mutex>

template <class T>
class Singleton
{
public:
    static T* GetSingleton()  //设计为静态成员函数:目的是在外部不用实例化对象,即可获得该单例
    {
        if(pSingleton == nullptr)  //第一个if判断:判断单例是否创建,创建了就跳出
        {
         	//线程锁:若同时有多个线程进入第一个if想创建对象,则需要排队。
         	//如果没有线程锁,同时有多个线程进入if判断,先后new了对象。前面new的对象的地址
         	//会被后面new的对象的地址覆盖,导致前面的new的对象造成内存泄漏。
            mxt.lock();            
            if(pSingleton == nullptr) //排队的线程,如果已经有一个创建了后面的判断一下,就不用再创建,直接跳出。
            {
                pSingleton = new T();
            }
            mxt.unlock();
        }
        return pSingleton;
    }

    static void Destroy()   //销毁单例
    {
        mxt.lock();
        if (pSingleton != nullptr)
        {
            delete pSingleton;
            pSingleton = nullptr;
        }
        mxt.unlock();
    }

private:
    static T* pSingleton;
    static std::mutex  mxt;
};

template <class T>
std::mutex Singleton<T>::mxt;

template <class T>
T* Singleton<T>::pSingleton = nullptr;

懒汉式举例

#include "Singleton/Singleton.h"

class GirlFriend
{
public:
    friend class Singleton<GirlFriend>; //因为单例类的构造函数为protected/private,因此外部需要调用它需要成员它的友元类。

    void show() const
    {
        std::cout << "身高:" << height << std::endl;
        std::cout << "年龄:" << age  << std::endl;
    }

private:
    GirlFriend() = default; //需要构建成单例的类,它的构造函数需要声明为protected/private类型,防止设计者在外部直接创建对象。即严格控制该类对象的创建方式。
    ~GirlFriend() = default;
    int age = 18;
    int height = 166;
};

main.cpp

#include <iostream>
#include "GirlFriend/GirlFriend.h"
#include "Singleton/Singleton.h"


int main() {
    Singleton<GirlFriend>::GetSingleton()->show();
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

结果

身高:166
年龄:18
Hello, World!

饿汉式

饿汉式单例的对象在程序启动时的静态初始化阶段创建(main 之前),而非编译时。 这种特性保证了多线程安全(C++11 及以上标准中,静态变量初始化是线程安全的),但可能提前占用资源(即使程序全程未使用该单例)

饿汉式代码举例

singleton.h

#ifndef SINGLETON_H
#define SINGLETON_H

class Singleton {
public:
    // 禁止拷贝构造和赋值操作
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    // 提供全局访问点,返回引用
    static Singleton& getInstance() {
        return instance;
    }

    // 示例成员函数
    void doSomething() {
        // 业务逻辑
    }

private:
    // 私有构造函数,防止外部实例化
    Singleton() = default;
    
    // 静态成员变量,程序启动时初始化
    static Singleton instance;
};

#endif // SINGLETON_H

singleton.cpp文件

#include "singleton.h"

// 初始化静态成员变量
Singleton Singleton::instance;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值