C++ 设计模式-单例模式

设计模式介绍

一、单例模式介绍

1. 单例模式定义

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2. 单例模式的本质

控制实例的数目

3. 单例模式的结构和说明

(1) 结构

C++ 设计模式-单例模式_第1张图片
Singleton:负责创建 Singleton类自己的唯一实例,并提供一个 getinstance I的方法,让外部来访问这个类的唯一实例。

(2) 调用顺序
懒汉式

C++ 设计模式-单例模式_第2张图片

饿汉式

C++ 设计模式-单例模式_第3张图片

4. 单例模式适用情况

当需要控制一个类的实例只能有一个,而且客户只能从一个全局访问点访问它时,可以选用单例模式,这些功能恰好是单例模式要解决的问题。

5. 单例模式优缺点

  • 时间和空间
    懒汉式典型的时间换空间, 饿汉式典型的空间换时间

懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间。
饿汉式是典型的空间换时间,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,节省了运行时间。

  • 线程安全
    不加同步的懒汉式是线程不安全的, 饿汉式是线程安全的

当然懒汉式也是可以实现线程安全的, 可以采取双重加锁检查的方法

6. 相关模式

很多模式都可以使用单例模式,只要这些模式中的某个类,需要控制实例为一个的时候,就可以很自然地使用上单例模式。比如抽象工厂方法中的具体工厂类就通常是个单例

二、单例模式示例代码

这里只介绍比较常见的经典方式,其他奇淫巧技不做介绍

1. 懒汉式

#include 
#include 
#include 
#include 

using namespace std;

template 
class Singleton{
public:
    template 
    static T* Instance(Args&&... args){
        if(m_instance == nullptr){
            std::unique_lock lock(mutex);
            if(m_instance == nullptr){
                m_instance = new T(std::forward(args)...);
            }
        }
        return m_instance;
    }

    Singleton() = delete;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(Singleton&&) = delete;
private:
    static T* m_instance;
    std::mutex;
};
template  T* Singleton::m_instance = nullptr;


//test
struct A
{
    A(const string&){cout<<"lvaue"<::Instance(str);

    //创建B类型的单例,临时变量str被move之后变成右值,然后可以根据移动语义来避免复制
    Singleton::Instance(std::move(str));

    // 创建C类型的单例,含两个参数
    Singleton::Instance(1, 3.14)->Fun();
    return 0;
}

2. 饿汉式

#include 
#include 
#include 

using namespace std;

template 
class Singleton{
public:
    static T* Instance(){
        return &m_instance;
    }

    Singleton() = delete;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(Singleton&&) = delete;
private:
    static T m_instance;
};
template  T Singleton::m_instance;

struct A
{
    A() = default;
    void Fun(){std::cout<<"A::Fun"<::Instance()->Fun();
    Singleton::Instance()->Fun();

    return 0;
}

3. 静态局部变量式

#include 
#include 
#include 

using namespace std;

template 
class Singleton{
public:
    template 
    static inline T& GetInstance(Args&&... args){
        static T obj {std::forward(args)...};
        return obj;
    }

    template 
    static inline T* GetInstancePtr(Args... args){
        return &GetInstance(args...);
    }

    Singleton() = delete;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(Singleton&&) = delete;
};

//test
struct A
{
    A(const string&){cout<<"lvaue"<::GetInstance(str);

    //创建B类型的单例,临时变量str被move之后变成右值,然后可以根据移动语义来避免复制
    Singleton::GetInstance(std::move(str));

    // 创建C类型的单例,含两个参数
    auto ptr = Singleton::GetInstancePtr(1, 3.14);
    // 获取单例并调用单例对象的方法
    ptr->Fun();

    return 0;
}

你可能感兴趣的:(设计模式,C++语法,c++)