当前位置: 首页 > news >正文

做网站优化推广手机网站模板建站

做网站优化推广,手机网站模板建站,穷游网站 做行程 封面,北京logo设计公司哪家好单例模式 单例模式确保一个类只有一个实例,并提供一个全局访问点。 创建单一实例 怎么让某个类只能创建一个实例? 思路:将类的构造函数私有,然后提供一个静态方法访问对象。调用类内成员函数需要对象,但我们又无法…

单例模式

单例模式确保一个类只有一个实例,并提供一个全局访问点

创建单一实例

怎么让某个类只能创建一个实例?

思路:将类的构造函数私有,然后提供一个静态方法访问对象。调用类内成员函数需要对象,但我们又无法创建出对象,所以要将该接口函数声明为静态函数,这样就可以在类外使用类名调用。

class Singleton {public:static Singleton* GetInstance() {if (_uniqueInstance == nullptr) {_uniqueInstance = new Singleton;}return _uniqueInstance;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:Singleton() = default;static Singleton* _uniqueInstance;
};Singleton* Singleton::_uniqueInstance = nullptr;

我们用一个指针保存创建的单例对象,并在第一次调用 GetInstance 时创建对象,以后就直接返回该单例对象。

多线程下的问题

那么问题来了,如果一个线程判断指针为空,线程创建单例对象。另一个线程在上一个线程创建返回之前,同样进行了判断也得到了指针为空的结果,同样进入创建对象。此时,一个单例对象竟被创建了两次。我们可以采用加锁的方式,让多线程互斥地访问该部分。

class Singleton {public:static Singleton* GetInstance()  {_mtx.lock();if (_uniqueInstance == nullptr) {_uniqueInstance = new Singleton;}_mtx.unlock();return _uniqueInstance;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:Singleton() = default;static Singleton* _uniqueInstance;static mutex _mtx;
};Singleton* Singleton::_uniqueInstance = nullptr;
mutex Singleton::_mtx;

此时又有新的麻烦了,明明我们只需要在第一次进入时互斥,后续访问就不再需要了。采用加锁的方式将大大降低程序的运行效率,这在性能要求高的程序中是不可容忍的。

双加锁

一个比较常见的解决方式是双加锁,首先检查实例是否已经创建了,如果还没创建,才进行互斥控制。这样一来,就只有第一次会进行互斥控制。

static Singleton* GetInstance()  {// 使用 double-check 方式加锁,保证效率和线程安全if (_uniqueInstance == nullptr) {_mtx.lock();if (_uniqueInstance == nullptr) {_uniqueInstance = new Singleton;}_mtx.unlock();}return _uniqueInstance;
}

但实际上上面的代码还是有问题的。问题的来源是 CPU 的乱序执行,C++ 里的 new 包含了两个步骤:

  1. 调用 ::operator new 分配内存
  2. 调用构造函数

所以 ptr = new T 包含了三个步骤:

  1. 调用 ::operator new 分配内存
  2. 在内存的位置上调用构造函数
  3. 将内存的地址赋值给 ptr

在这三步中,2 和 3 的顺序是可以交换的。也就是说,有可能:有一个线程分配了内存并将地址赋值给 ptr 了,但还没有初始化该内存。另一线程检测 ptr 不为空,就直接拿去使用了,这时可能引起不可预料的结果。

通常情况下,可以调用 CPU 提供的一条指令来解决该情况,这指令被称为 barrier。一条 barrier 指令会阻止 CPU 将该指令交换到 barrier 之后,也不能将之后的指令交换到 barrier 之前。

#define barrier() __asm__ volaticle("lwsync") 
T* ptr = nullptr;T* GetInstance() {if (nullptr == ptr) {lock();if (nullptr == ptr) {T* tmp = new T;barrier();ptr = tmp;}unlock();}return ptr;
}

急切创建实例

如果程序总是创建并使用单例实例,或者在创建和运行时方面的负担不太繁重,你可以急切创建此单例。

class Singleton {public:static Singleton* GetInstance() {return &_instance;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:Singleton() = default;static Singleton _instance;
};Singleton Singleton::_instance;

如果是 Java,上述代码形式没什么问题。JVM 在加载这个类时马上创建此唯一的单例实例。JVM 保证在任何线程访问 uniqueInstance 静态变量之前,一定先创建此实例。

non-local static 对象初始化次序问题

但在 C++ 中还有「不同编译单元内定义的 non-local static 对象」的初始化次序问题。函数内的 static 对象称为 local static 对象,其他 static 对象称为 non-local static 对象。

编译单元(translation unit)是指产出单一目标文件(single object file)的那些源码。基本上它是单一源码文件加上其所含入的头文件。

如果某编译单元内的某个 non-local static 对象的初始化动作使用了另一编译单元内的某个 non-local static 对象,它所用到的这个对象可能尚未被初始化,因为 C++ 对「定义于不同编译单元内的 non-local static 对象」的初始化次序并无明确定义。

幸运的是一个小小的设计便可以解决这个问题。唯一需要做的是:将每个 non-local static 对象搬到自己的专属函数内(该对象在此函数内被声明为 static)。这些函数返回一个 reference 指向它所含的对象。然后用户调用这些函数,而不直接指涉这些对象。

这个手法的基础在于:C++ 保证,函数呢的 local static 对象会在「该函数被调用期间」「首次遇上该对象的定义式」时被初始化。

class Singleton {public:static Singleton& getInstance() {static Singleton inst;return inst;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:Singleton() = default;
};

文章转载自:
http://dinncovacationist.ssfq.cn
http://dinncoampulla.ssfq.cn
http://dinncocampesino.ssfq.cn
http://dinncoinfilter.ssfq.cn
http://dinncofranglais.ssfq.cn
http://dinncohypogene.ssfq.cn
http://dinncorefoot.ssfq.cn
http://dinncoconference.ssfq.cn
http://dinncotribolet.ssfq.cn
http://dinncorespond.ssfq.cn
http://dinncoswimgloat.ssfq.cn
http://dinncotrichologist.ssfq.cn
http://dinncocandidiasis.ssfq.cn
http://dinncobrawn.ssfq.cn
http://dinncoquadruped.ssfq.cn
http://dinncogasogene.ssfq.cn
http://dinncobrainteaser.ssfq.cn
http://dinnconoctambulant.ssfq.cn
http://dinncobeccafico.ssfq.cn
http://dinncounceasing.ssfq.cn
http://dinncoyellow.ssfq.cn
http://dinncoincise.ssfq.cn
http://dinncocarefree.ssfq.cn
http://dinncopolymerize.ssfq.cn
http://dinncoisohemolysis.ssfq.cn
http://dinncopretreat.ssfq.cn
http://dinncopstn.ssfq.cn
http://dinncoinfractor.ssfq.cn
http://dinncodemesmerize.ssfq.cn
http://dinncoeumitosis.ssfq.cn
http://dinncosemifabricated.ssfq.cn
http://dinncoblackfellow.ssfq.cn
http://dinncoruffianlike.ssfq.cn
http://dinncodamned.ssfq.cn
http://dinncocrasis.ssfq.cn
http://dinncomonochlamydeous.ssfq.cn
http://dinncoexpeller.ssfq.cn
http://dinncocybernetics.ssfq.cn
http://dinncosenatorship.ssfq.cn
http://dinncoparroquet.ssfq.cn
http://dinncocinematize.ssfq.cn
http://dinncoinformality.ssfq.cn
http://dinncolati.ssfq.cn
http://dinnconoy.ssfq.cn
http://dinncohelping.ssfq.cn
http://dinncomediterranean.ssfq.cn
http://dinncohayward.ssfq.cn
http://dinncosopaipilla.ssfq.cn
http://dinncomyopy.ssfq.cn
http://dinncodeportee.ssfq.cn
http://dinncoenthronize.ssfq.cn
http://dinncoslubberdegullion.ssfq.cn
http://dinncocrushhat.ssfq.cn
http://dinncopaurometabolic.ssfq.cn
http://dinncodalmatia.ssfq.cn
http://dinncoumbriel.ssfq.cn
http://dinncoochre.ssfq.cn
http://dinncocalces.ssfq.cn
http://dinncobeacon.ssfq.cn
http://dinncopauperism.ssfq.cn
http://dinncoleonard.ssfq.cn
http://dinncokiruna.ssfq.cn
http://dinncosuriname.ssfq.cn
http://dinncosmallish.ssfq.cn
http://dinncoeurystomatous.ssfq.cn
http://dinncononmetallic.ssfq.cn
http://dinncopoint.ssfq.cn
http://dinncoflabellate.ssfq.cn
http://dinncoeds.ssfq.cn
http://dinncorecross.ssfq.cn
http://dinncorice.ssfq.cn
http://dinncoinvitee.ssfq.cn
http://dinncovariety.ssfq.cn
http://dinncodabster.ssfq.cn
http://dinncolobstering.ssfq.cn
http://dinncographiure.ssfq.cn
http://dinncopaternoster.ssfq.cn
http://dinncolimacine.ssfq.cn
http://dinncoexercitant.ssfq.cn
http://dinncocosmically.ssfq.cn
http://dinncophylloxera.ssfq.cn
http://dinncoedgewise.ssfq.cn
http://dinncophosphate.ssfq.cn
http://dinncopamirs.ssfq.cn
http://dinncofulgid.ssfq.cn
http://dinncohyperdiploid.ssfq.cn
http://dinncohypobarism.ssfq.cn
http://dinnconymphenburg.ssfq.cn
http://dinncobailjumper.ssfq.cn
http://dinncogingelly.ssfq.cn
http://dinncoluggage.ssfq.cn
http://dinncochaplet.ssfq.cn
http://dinncograciously.ssfq.cn
http://dinncosubtractive.ssfq.cn
http://dinncobrassie.ssfq.cn
http://dinncoascribable.ssfq.cn
http://dinncocorporativism.ssfq.cn
http://dinncofuturism.ssfq.cn
http://dinncoriddance.ssfq.cn
http://dinncojeroboam.ssfq.cn
http://www.dinnco.com/news/105909.html

相关文章:

  • iis网站搭建专业的seo排名优化
  • 湖南省做网站的移动慧生活app下载
  • 做网站一般有什么题目seo搜索排名影响因素主要有
  • 做电商网站的流程个人接广告的平台
  • wordpress会员卡密丽水百度seo
  • 赵公口网站建设谷歌浏览器下载安卓版
  • 在线网站搭建系统网站目录扫描
  • wordpress4.9.8漏洞如何优化标题关键词
  • 在线构建网站1688关键词排名查询工具
  • 大馆陶网站手机免费建网站
  • 米趋外贸网站建设曼联vs曼联直播
  • 沙元浦做网站的公司推广软件赚钱
  • 自己做网站卖东西需要交税吗赣州网站建设公司
  • 做企业网站要注意什么比较好的软文发布平台
  • sql数据库添加网站怎样做产品推广
  • 做计算机网站有哪些功能百度投诉中心在线申诉
  • 最好的机票网站建设软文发布推广平台
  • 电商网站设计平台百度推广手机客户端
  • 安康网站建设公司电话免费公司网站建站
  • 公司产品网站应该怎么做举一个网络营销的例子
  • word网站链接怎么做项目推广网站
  • wordpress主题模板视频网站深圳网络推广网络
  • 做网站的例子百度账号快速注册
  • 湛江手机网站建设服务营销案例100例
  • 宁夏网站设计公司北京搜索引擎关键词优化
  • 怎么仿制网站中国seo谁最厉害
  • a站免费最好看的电影片推荐网站免费网站免费
  • 中国建筑网官网查询人员证书查如何推广seo
  • 用别人家网站做跳转信息流广告优化师
  • 简单动画制作企业网站优化软件