c++中单例模式总结

程序员小x大约 2 分钟C++

c++中单例模式总结

通常而言,c++的单例模式通常有如下一些实现办法:

  • 普通懒汉
  • 加锁懒汉
  • 静态内部变量
  • 饿汉单例
  • std::call_once单例

普通懒汉

对于普通懒汉:

  • 构造函数和析构函数应该为private类型,禁止外部构造和析构
  • 拷贝构造函数赋值运算符应为private类型或者加上** = delete**标记,禁止外部拷贝和赋值,确保单例的唯一性
  • Singleton的有一个静态的函数getInstance用于获取静态对象。
#include <iostream>

class Singleton
{
public:
    static Singleton* getInstance();
    static void destroy();

public:
    Singleton(const Singleton& instance) = delete;
    const Singleton& operator=(const Singleton& instance) = delete;

private:
    Singleton();
    ~Singleton();
private:
    static Singleton* m_singletonInstance;
};

Singleton* Singleton::m_singletonInstance = nullptr;

Singleton* Singleton::getInstance()
{
    if(nullptr == m_singletonInstance)
    {
        m_singletonInstance = new Singleton; 
    }
    return m_singletonInstance;
}

void Singleton::destroy()
{
    if(m_singletonInstance)
    {
        delete m_singletonInstance;
        m_singletonInstance = nullptr;
    }
}
Singleton::Singleton()
{
    std::cout << "create instance" << std::endl;
}

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

int main()
{
    Singleton* instance = Singleton::getInstance();
    instance->destroy();
}

普通懒汉会有很明显的线程安全问题,不能严格地做到单例。

普通懒汉的线程安全问题
普通懒汉的线程安全问题

加锁懒汉

加锁懒汉的最经典的实现是Double-Checked Locking Pattern (DCLP),如下所示:

#include <iostream>
#include <mutex>

class Singleton
{
public:
    static Singleton* getInstance();
    static void destroy();

public:
    Singleton(const Singleton& instance) = delete;
    const Singleton& operator=(const Singleton& instance) = delete;

private:
    Singleton();
    ~Singleton();
private:
    static Singleton* m_singletonInstance;
    static std::mutex m_Mutex;
};

Singleton* Singleton::m_singletonInstance = nullptr;
std::mutex Singleton::m_Mutex;

Singleton* Singleton::getInstance()
{
    if(nullptr == m_singletonInstance)
    {
        std::unique_lock<std::mutex> lk(m_Mutex);
        if(nullptr == m_singletonInstance)
        {
            m_singletonInstance = new Singleton; 
        }

    }
    return m_singletonInstance;
}

void Singleton::destroy()
{
    std::unique_lock<std::mutex> lk(m_Mutex);
    if(m_singletonInstance)
    {
        delete m_singletonInstance;
        m_singletonInstance = nullptr;
    }
}
Singleton::Singleton()
{
    std::cout << "create instance" << std::endl;
}

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

int main()
{
    Singleton* instance = Singleton::getInstance();
    instance->destroy();
}

在单例创建时,使用了mutex进行加锁操作,可以一定程度上保证线程安全。但是要注意这种方式也不能完全保证线程安全。

可以使用volatile进行优化

静态内部变量

#include <iostream>
#include <mutex>

class Singleton
{
public:
    static Singleton& getInstance();

public:
    Singleton(const Singleton& instance) = delete;
    const Singleton& operator=(const Singleton& instance) = delete;

private:
    Singleton();
    ~Singleton();

};


Singleton& Singleton::getInstance()
{
    static Singleton singleton;
    return singleton;
}


Singleton::Singleton()
{
    std::cout << "create instance" << std::endl;
}

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

int main()
{
    Singleton& instance = Singleton::getInstance();
}

饿汉单例

#include <iostream>

class Singleton
{
public:
    static Singleton* getInstance();
    static void destroy();

public:
    Singleton(const Singleton& instance) = delete;
    const Singleton& operator=(const Singleton& instance) = delete;

private:
    Singleton();
    ~Singleton();
private:
    static Singleton* m_singletonInstance;
};

Singleton* Singleton::m_singletonInstance = new Singleton;

Singleton* Singleton::getInstance()
{
    return m_singletonInstance;
}

void Singleton::destroy()
{
    if(m_singletonInstance)
    {
        delete m_singletonInstance;
        m_singletonInstance = nullptr;
    }
}
Singleton::Singleton()
{
    std::cout << "create instance" << std::endl;
}

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

int main()
{
    Singleton* instance = Singleton::getInstance();
    instance->destroy();
}

std::call_once单例

参考文章: https://www.cnblogs.com/xiaolincoding/p/11437231.htmlopen in new window

https://blog.csdn.net/u011726005/article/details/82356538open in new window

https://blog.csdn.net/bdss58/article/details/44813597open in new window

Loading...