曂沅仴駦 发表于 2024-6-11 09:00:21

C++单例模式

 C++ 单例模式_c++单例模式-CSDN博客
文章内容来自上面的文章
#include <iostream>
#include "widget.h"
using namespace std;

/*
*        版本1 SingletonPattern_V1 存在以下两个问题
*
*        1. 线程不安全, 非线程安全版本
*        2. 内存泄露
*/

class SingletonPattern_V1
{
private:
    SingletonPattern_V1() {
      cout << "constructor called!" << endl;
    }
    SingletonPattern_V1(SingletonPattern_V1&) = delete;
    SingletonPattern_V1& operator=(const SingletonPattern_V1&) = delete;
    static SingletonPattern_V1* m_pInstance;

public:
    ~SingletonPattern_V1() {
      cout << "destructor called!" << endl;
    }
    //在这里实例化
    static SingletonPattern_V1* Instance() {
      if (!m_pInstance) {
            m_pInstance = new SingletonPattern_V1();
      }
      return m_pInstance;
    }
    void use() const { cout << "in use" << endl; }
};
//在类外初始化静态变量
SingletonPattern_V1* SingletonPattern_V1::m_pInstance = nullptr;

//函数入口
int main(int argc, char *argv[])
{
    //测试
    SingletonPattern_V1* p1 = SingletonPattern_V1::Instance();
    SingletonPattern_V1* p2 = SingletonPattern_V1::Instance();
    p1->use();
    p2->use();
    return 0;
}
   constructor called!
in use
in use
容易知道此时是内存泄漏的 
线程安全:
多线程中:
static SingletonPattern_V1* Instance() {
                if (!m_pInstance) {
                        m_pInstance = new SingletonPattern_V1();
                }
                return m_pInstance;
        } 实行该段代码时,if(!m_pInstance),如果线程A和线程B都判定为空,都开始初始化实例,那么会初始化两次.此时需要加锁.
办理题目后的代码:
#include <iostream>
using namespace std;
#include <memory> // C++11 shared_ptr头文件
#include <mutex>// C++11 mutex头文件
/*
*        版本2 SingletonPattern_V2 解决了V1中的问题
*
*        1. 通过加锁让线程安全了
*        2. 通过智能指针(shareptr 基于引用计数)内存没有泄露了
*/
class SingletonPattern_V2
{
public:
        ~SingletonPattern_V2() {
                std::cout << "destructor called!" << std::endl;
        }
        SingletonPattern_V2(SingletonPattern_V2&) = delete;
        SingletonPattern_V2& operator=(const SingletonPattern_V2&) = delete;

        //在这里实例化
        static std::shared_ptr<SingletonPattern_V2> Instance()
        {
                //双重检查锁
                if (m_pInstance == nullptr) {
                        std::lock_guard<std::mutex> lk(m_mutex);
                        if (m_pInstance == nullptr) {
                                m_pInstance = std::shared_ptr<SingletonPattern_V2>(new SingletonPattern_V2());
                        }
                }
                return m_pInstance;
        }

private:
        SingletonPattern_V2() {
                std::cout << "constructor called!" << std::endl;
        }
        static std::shared_ptr<SingletonPattern_V2> m_pInstance;
        static std::mutex m_mutex;
};

//在类外初始化静态变量
std::shared_ptr<SingletonPattern_V2> SingletonPattern_V2::m_pInstance = nullptr;
std::mutex SingletonPattern_V2::m_mutex;

int main()
{
        std::shared_ptr<SingletonPattern_V2> p1 = SingletonPattern_V2::Instance();
        std::shared_ptr<SingletonPattern_V2> p2 = SingletonPattern_V2::Instance();

        system("pause");
        return 0;
} 用智能共享指针和锁把上面的题目给办理了. 
SingletonPattern_V2(SingletonPattern_V2&) = delete; C++11中=delete的奇妙用法_= delete-CSDN博客


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: C++单例模式