您的位置:首页 > 教育 > 培训 > 汕头网站制作怎么做_知名个人网站_深圳网站设计三把火_网店推广方式

汕头网站制作怎么做_知名个人网站_深圳网站设计三把火_网店推广方式

2024/10/5 16:29:27 来源:https://blog.csdn.net/Edward1027/article/details/142468329  浏览:    关键词:汕头网站制作怎么做_知名个人网站_深圳网站设计三把火_网店推广方式
汕头网站制作怎么做_知名个人网站_深圳网站设计三把火_网店推广方式

文章目录

    • 一、要点
    • 二、代码
      • 1.核心代码
      • 2.详细注释代码
      • 3.无注释代码 (单线程时,存在线程安全问题)
      • 4.考虑线程安全 (getInstance加锁)
        • 4.1 进一步减少加锁的开销,使用双重检查锁
      • 5.释放单例资源以避免内存泄露(智能指针)
      • 6.饿汉式

在这里插入图片描述

一、要点

0.单例模式,顾名思义只能有一个实例对象
1.私有化构造函数:不能随便调用构造函数来实例化对象
2.删除拷贝构造函数、赋值运算符函数:确保唯一实例
3.使用静态成员变量,存储指向单例对象的指针:静态方法属于类,不属于具体的实例对象。
4.提供静态方法,在堆上获取单例对象


二、代码

延迟实例化、懒加载、懒汉式:实例在第一次使用时才会被创建


1.核心代码

static Singleton* getInstance() {if (instance == nullptr) {instance = new Singleton();  // 只有在第一次调用时创建实例}return instance;
}

2.详细注释代码

#include <iostream> 
using std::cout;
using std::endl;//单例模式:要通过给的接口来创造唯一实例。
//因此,要将构造函数私有化,并且删除拷贝构造和赋值运算符函数class Singleton
{
public://静态方法,用于获取唯一的实例。静态方法属于类,而非实例对象//懒加载、懒汉式、延迟实例化static Singleton* getInstance(){if(pInstance == nullptr){pInstance = new Singleton(); }return pInstance;}void display(){cout << "This is the Singleton instance." << "\n";}
private://构造函数私有化,防止外部创建对象Singleton(){cout << "Singleton instance created.\n";}//禁用拷贝构造和赋值运算符函数Singleton(const Singleton & ) = delete;Singleton & operator=(const Singleton &) = delete;//静态成员变量,存储唯一的实例static Singleton* pInstance;
};//类外初始化静态成员变量
Singleton* Singleton::pInstance = nullptr;int main()
{//获取单例对象的唯一实例Singleton* s1 = Singleton::getInstance();s1->display();//再次获取单例对象的实例Singleton* s2 = Singleton::getInstance();s2->display();//验证两个指针是否指向同一个实例if(s1 == s2){cout << "Both pointer point to the same instance.\n";}return 0;
}

另一版

#include <iostream> 
using std::cout;
using std::endl;//单例模式:要通过给的接口来创造唯一实例。
//因此,要将构造函数私有化,并且删除拷贝构造和赋值运算符函数class Singleton
{
private://构造函数私有化,防止外部创建对象Singleton(){cout << "Singleton instance created.\n";}//禁用拷贝构造和赋值运算符函数Singleton(const Singleton & ) = delete;Singleton & operator=(const Singleton &) = delete;//静态成员变量,存储唯一的实例static Singleton* instance;
public://静态方法,用于获取唯一的实例static Singleton* getInstance(){if(instance == nullptr){instance = new Singleton(); //延迟实例化}return instance;}void display(){cout << "This is the Singleton instance." << "\n";}
};//静态成员变量初始化为nullptr
Singleton* Singleton::instance = nullptr;int main()
{//获取单例对象的唯一实例Singleton* s1 = Singleton::getInstance();s1->display();//再次获取单例对象的实例Singleton* s2 = Singleton::getInstance();s2->display();//验证两个指针是否指向同一个实例if(s1 == s2){cout << "Both pointer point to the same instance.\n";}return 0;
}

3.无注释代码 (单线程时,存在线程安全问题)

#include <iostream> 
using std::cout;
using std::endl;class Singleton
{
public:static Singleton* getInstance(){if(pInstance == nullptr){pInstance = new Singleton();}return pInstance;}private:Singleton(){};Singleton(const Singleton & rhs) = delete;Singleton & operator= (const Singleton & rhs) = delete;static Singleton* pInstance;
};Singleton* Singleton::pInstance = nullptr;int main()
{Singleton* s1 = Singleton::getInstance();Singleton* s2 = Singleton::getInstance();if(s1 == s2){cout << "s1 == s2,是单例的\n";}else{cout << "s1 != s2,不是单例的\n";}return 0;
}

4.考虑线程安全 (getInstance加锁)

#include <iostream> 
#include <mutex>
using std::cout;
using std::mutex;
using std::lock_guard;class Singleton
{
public:static Singleton* getInstance(){lock_guard<mutex> lock(mtx);if(pInstance == nullptr){pInstance = new Singleton();}return pInstance;}private:Singleton(){};Singleton(const Singleton & rhs) = delete;Singleton & operator= (const Singleton & rhs) = delete;static Singleton* pInstance;static mutex mtx; //互斥锁,确保线程安全
};Singleton* Singleton::pInstance = nullptr;
mutex Singleton::mtx;int main()
{Singleton* s1 = Singleton::getInstance();Singleton* s2 = Singleton::getInstance();if(s1 == s2){cout << "s1 == s2,是单例的\n";}else{cout << "s1 != s2,不是单例的\n";}return 0;
}

4.1 进一步减少加锁的开销,使用双重检查锁
// 线程安全的 getInstance 方法,使用双重检查锁
static Singleton* getInstance()
{if(pInstance == nullptr) {  // 第一次检查,无锁std::lock_guard<std::mutex> lock(mtx);  // 加锁if(pInstance == nullptr) {  // 第二次检查,加锁后pInstance = new Singleton();}}return pInstance;
}

5.释放单例资源以避免内存泄露(智能指针)

#include <iostream> 
#include <mutex>
#include <memory>using std::cout;
using std::mutex;
using std::lock_guard;
using std::unique_ptr;class Singleton
{
public:static Singleton* getInstance(){lock_guard<mutex> lock(mtx);if(pInstance == nullptr){/* pInstance = new Singleton(); */pInstance = unique_ptr<Singleton>(new Singleton());}return pInstance.get();}private:Singleton(){};Singleton(const Singleton & rhs) = delete;Singleton & operator= (const Singleton & rhs) = delete;/* static Singleton* pInstance; */static unique_ptr<Singleton> pInstance;static mutex mtx; //互斥锁,确保线程安全
};/* Singleton* Singleton::pInstance = nullptr; */
unique_ptr<Singleton> Singleton::pInstance = nullptr;
mutex Singleton::mtx;int main()
{Singleton* s1 = Singleton::getInstance();Singleton* s2 = Singleton::getInstance();if(s1 == s2){cout << "s1 == s2,是单例的\n";}else{cout << "s1 != s2,不是单例的\n";}return 0;
}

6.饿汉式

饿汉式:在类加载时就进行实例化

#include <iostream>
using namespace std;class Singleton{
public:// 提供全局访问点static Singleton& getInstance(){// 静态局部变量在程序启动时初始化static Singleton instance;return instance;}// 删除拷贝构造函数和赋值操作符,防止复制Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;// 示例方法void display() const{cout << "Singleton::display() called on instance: " << this << endl;}
private:// 私有构造函数Singleton(){cout << "Singleton()" << endl;}// 私有析构函数~Singleton(){cout << "~Singleton()" << endl;}
};int main()
{// 通过getInstance获取单例对象的引用,并调用示例方法Singleton& s1 = Singleton::getInstance();s1.display();// 再次获取单例对象的引用,验证它们是同一个实例Singleton& s2 = Singleton::getInstance();s2.display();// 输出将展示s1和s2有相同的地址,说明它们是同一个实例return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com