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

武汉网站快照推广做推广

武汉网站快照推广,做推广,微官网和微网站首页,国外做珠宝裸石的网站1.前言 在实际场景中,总会遇见一些特殊情况,比如设计一个类,只能在堆上开辟空间, 或者是设计一个类只能实例化一个对象。那么我们应该如何编写代码呢?本篇将会详细的介绍 本章重点: 本篇文章着重讲解如何设计一些特殊 的类,包括不能被拷贝,只能在栈/堆上…

1.前言

在实际场景中,总会遇见一些特殊情况,比如设计一个类,只能在堆上开辟空间,
或者是设计一个类只能实例化一个对象。那么我们应该如何编写代码呢?本篇将会详细的介绍

本章重点:

本篇文章着重讲解如何设计一些特殊
的类,包括不能被拷贝,只能在栈/堆上
创建对象以及此类只能实例化一个对象,
这也是我们听说过的单例模式,单例模式又
包含饿汉和懒汉模式,文章都是干货
请同学们耐心学习!

2.设计一个不能被拷贝/继承的类

1.设计一个类,不能被拷贝

在设计这个类之前,需要明确的是:拷贝只会放生在两个场景中拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝, 只需让该类不能调用拷贝构造函数以及赋值运算符重载即可

在c++98中一般操作就是在私有中把这两个函数只声明,不定义。

class CopyBan
{private:CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);
};

原因:

1. 设置成私有:如果只声明没有设置成private,用户自己如果在类外定义了,就可以不
能禁止拷贝了
2. 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写
反而还简单,而且如果定义了就不会防止成员函数内部拷贝了。
C++11扩展 delete 的用法, delete 除了释放 new申请的资源外,如果在默认成员函数后跟上
=delete,表示让编译器删除掉该默认成员函数。
class CopyBan
{CopyBan(const CopyBan&)=delete;CopyBan& operator=(const CopyBan&)=delete;
};

2.设计一个不能被继承的类

c++11中可以直接使用关键字final

class A  final
{// ....
};

 c++98:基类的构造函数私有化,这样子类在创建对象时,属于基类的那一部分会调用基类的构造函数初始化,那么由于基类的构造函数私有化了,因此无法初始化,直接报错。

class NonInherit
{
private:NonInherit(){}
};

3.设计只能在堆上创建对象的类

只能在堆上创建对象,那么就表明所有创建的对象经过的构造函数都要用new来构造,这样才能够满足要求。

除此之外还要禁止拷贝构造和赋值函数,因为这样可以防止别人调用拷贝或者赋值重载函数来生成对象

class HeapOnly    
{     
public:     static HeapOnly* CreateObject()  {      return new HeapOnly;    }
private:    HeapOnly() {}// C++98// 1.只声明,不实现。因为实现可能会很麻烦,而你本身不需要// 2.声明成私有HeapOnly(const HeapOnly&);// or// C++11    HeapOnly(const HeapOnly&) = delete;
};

解释为什么这里使用的是static:

 将构造函数设置为私有后,不管是在堆上还是栈上都不能创建对象,但是我们可以在共有域写一个函数显示去调用构造函数,注意,这里的共有域函数必须设置为static类型,因为必须有了对象后才能调用函数,但是要调用了此函数才能创建对象,就会出现先有鸡还是先有蛋的问题,所以设置为static后,可以用类域调用!

方法二:将析构函数封掉。

 先解释为什么这个方法可行。一般来说:
C++是静态绑定的语言在编译时期,所有的非虚函数调用都必须分析完成。则当对象建立在栈上面时,是由编译器分配内存空间的,调用构造函数来构造栈对象。当对象使用完后,编译器会调用析构函数来释放栈对象所占的空间。编译器管理了对象的整个生命周期(具体过程为: 通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数 )。所以,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性(其实不光是析构函数,只要是非静态的函数,编译器都会进行检查)。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存所以 析构函数私有化的类的设计可以保证只能用new命令在堆(heap)中创建对象。

//封析构函数
class HeapOnly
{
public:void destory(){delete this;}
private:~HeapOnly(){cout<<"调用析构成功!"<<endl;}
};

4.设计只能在栈上创建对象的类

只能在栈上创建对象的话,那么就必须把new 和delete函数给封掉。因为new这个函数创建的对象一定是在堆上的。那其他的设计思路就和上述设计只能在堆上创建对象类似了

class StackOnly
{
public:static StackOnly CreateObj(){return StackOnly();}// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
// StackOnly obj = StackOnly::CreateObj();
// StackOnly* ptr3 = new StackOnly(obj);void* operator new(size_t size) = delete;void operator delete(void* p) = delete;
private:StackOnly()  :_a(0){}private:int _a;
};

5.只能实例化一个对象的类

一个类只能实例化出一个对象,这就是大名鼎鼎的“单例模式”。

在阐述单例模式之前,我们先需要了解一下什么是设计模式。

什么是单例模式呢?

单例模式的运用是非常的广泛的,如在线程池里面等等,可以自行去搜索了解。

单例模式有两种实现的方式:1 .饿汉模式,就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象

2.懒汉模式:只有在使用的时候,才初始化出对象。

6.饿汉模式

注意,这里实现的是样例(demo)代码,在
不同的工程场景下需要大家做灵活的变换

在设计之前先明确的是:什么情况下才会只初始化出一个对象呢?不管其他在怎么做,都不会初始化其他的对象。---静态成员函数及变量。只会初始化一次。---于是单例模式就可以设计成静态函数。

// 饿汉模式
// 优点:简单
// 缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。
class Singleton
{
public:static Singleton* GetInstance(){return _ins;}
private://限制类外随意创建对象Singleton(const Singleton& s) = delete;Singleton& operator=(const Singleton& s) = delete;Singleton(){}
private:static Singleton* _ins;
};
Singleton* Singleton::_ins = new Singleton;

注意:类里面的静态成员变量只能在类中声明,定义必须在类的外面。

单例模式的饿汉模式中,程序一启动就会把_ins,也就是唯一的实例对象给初始化,
并且由于构造函数被私有了,只能调用共有的GetInstance()函数获取_ins对象,又
由于这个对象是static类型的,所以不管你调用多少次GetInstance()都获取的是同
一个对象,也就是_ins

7.懒汉模式

如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取
文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,
就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。
只有在使用的时候才进行初始化:
//懒汉模式
class Singleton
{
public:static Singleton* GetInstance(){if (_ins == nullptr){_ins = new Singleton;}return _ins;}void DelInstance(){if (_ins != nullptr){cout << "over!!!" << endl;delete _ins;_ins = nullptr;}}
private://限制类外随意创建对象Singleton(const Singleton& s) = delete;Singleton& operator=(const Singleton& s) = delete;Singleton(){}
private:static Singleton* _ins;};
Singleton* Singleton::_ins = nullptr;

但是这样在多线程的情况下会有一个问题,多个线程同时进入getinstance函数,这就导致多个线程都生成了一个对象。这和我们要求的一个类只能创建一个对象时不符合的。所以说我们要对这种不是原子的操作进行加锁(原子的操作学linux和mysql时会讲到)

修改代码如下:

//懒汉模式
class Singleton
{
public:static Singleton* GetInstance(){if (_ins == nullptr)//双检查加锁,只有第一次进来时需要加锁,其他情况不用加锁{mtx.lock();if (_ins == nullptr)//第一次调用才创建实例!{_ins = new Singleton;}mtx.unlock();}return _ins;}void DelInstance(){mtx.lock();if (_ins != nullptr){cout << "over!!!" << endl;delete _ins;_ins = nullptr;}mtx.unlock();}
private://限制类外随意创建对象Singleton(const Singleton& s) = delete;Singleton& operator=(const Singleton& s) = delete;Singleton(){}
private:static Singleton* _ins;static mutex mtx;
};
Singleton* Singleton::_ins = nullptr;
mutex Singleton::mtx;

8.总结与拓展

特殊类的设计和单例模式就讲到这了,只单说概念其实大家对于单例模式的强大性还是理解的不够深刻,只有在结合项目一起使用时,那么理解就会快速增加了。

拓展:单例模式只是设计模式中的一种,还有工厂模式,适配器模式等等,有想了解这些设计模式的可以自行查阅资料。

设计模式 - 概览 | C++ 全栈知识体系 (stibel.icu)


文章转载自:
http://lacedaemonian.bbrf.cn
http://nohow.bbrf.cn
http://pollakiuria.bbrf.cn
http://reticulosis.bbrf.cn
http://sarasota.bbrf.cn
http://sacral.bbrf.cn
http://uno.bbrf.cn
http://tumorous.bbrf.cn
http://greasiness.bbrf.cn
http://previse.bbrf.cn
http://clicketyclack.bbrf.cn
http://arioso.bbrf.cn
http://livelong.bbrf.cn
http://eleemosynary.bbrf.cn
http://liprouge.bbrf.cn
http://beguilement.bbrf.cn
http://appetency.bbrf.cn
http://except.bbrf.cn
http://hermitship.bbrf.cn
http://allograph.bbrf.cn
http://practicoinert.bbrf.cn
http://coralline.bbrf.cn
http://overcast.bbrf.cn
http://serene.bbrf.cn
http://router.bbrf.cn
http://gimcracky.bbrf.cn
http://niamey.bbrf.cn
http://phenylbutazone.bbrf.cn
http://indigosol.bbrf.cn
http://multiband.bbrf.cn
http://natatoria.bbrf.cn
http://devout.bbrf.cn
http://semispherical.bbrf.cn
http://rocketry.bbrf.cn
http://floweriness.bbrf.cn
http://except.bbrf.cn
http://retrospectively.bbrf.cn
http://formless.bbrf.cn
http://pda.bbrf.cn
http://cyberneticist.bbrf.cn
http://v.bbrf.cn
http://nincompoopery.bbrf.cn
http://fitter.bbrf.cn
http://linksman.bbrf.cn
http://hypoazoturia.bbrf.cn
http://distorted.bbrf.cn
http://recuperator.bbrf.cn
http://redux.bbrf.cn
http://satinwood.bbrf.cn
http://callose.bbrf.cn
http://eventuate.bbrf.cn
http://ndr.bbrf.cn
http://minicamera.bbrf.cn
http://psaltery.bbrf.cn
http://eumycete.bbrf.cn
http://accusable.bbrf.cn
http://mechanize.bbrf.cn
http://whoopee.bbrf.cn
http://semidaily.bbrf.cn
http://resubject.bbrf.cn
http://century.bbrf.cn
http://hypohepatia.bbrf.cn
http://vires.bbrf.cn
http://flopover.bbrf.cn
http://paralanguage.bbrf.cn
http://gothamite.bbrf.cn
http://actinomycosis.bbrf.cn
http://cheekpiece.bbrf.cn
http://rusticity.bbrf.cn
http://berg.bbrf.cn
http://umbel.bbrf.cn
http://blueprint.bbrf.cn
http://patinize.bbrf.cn
http://blousy.bbrf.cn
http://broadtail.bbrf.cn
http://libertyman.bbrf.cn
http://gingiva.bbrf.cn
http://sophister.bbrf.cn
http://linguatulid.bbrf.cn
http://musicotherapy.bbrf.cn
http://viraemia.bbrf.cn
http://mundane.bbrf.cn
http://carnarvon.bbrf.cn
http://ethambutol.bbrf.cn
http://watercolour.bbrf.cn
http://iridectomy.bbrf.cn
http://lapful.bbrf.cn
http://detassel.bbrf.cn
http://dispense.bbrf.cn
http://angiosperm.bbrf.cn
http://milkfish.bbrf.cn
http://matrilineal.bbrf.cn
http://magnetooptical.bbrf.cn
http://cloddish.bbrf.cn
http://hotbox.bbrf.cn
http://lame.bbrf.cn
http://jazzily.bbrf.cn
http://autoinjector.bbrf.cn
http://quadrangled.bbrf.cn
http://scleroma.bbrf.cn
http://www.15wanjia.com/news/80723.html

相关文章:

  • 宁远做网站徐州新站百度快照优化
  • 东莞如何制作自己的网站如何做好品牌宣传
  • 上海做公司网站的公司宁波网络推广软件
  • 网站建设服务清单泽成杭州seo网站推广排名
  • 如何制作课程网站模板网站优化人员通常会将目标关键词放在网站首页中的
  • 东莞 网站 建设b2b平台
  • 做动态网站什么语言好深圳百度竞价托管公司
  • 网站加入视频sem是什么牌子
  • 怎么建立个人网站哪里可以引流到精准客户呢
  • 哪类型网站容易做北京计算机培训机构哪个最好
  • 创建网站的软件网络广告发布
  • sb域名怎么注册徐州seo推广
  • 中国国内b2b网站产品网络推广
  • 如何防止网站被注入黑链外贸网站建设优化
  • 以绿色为主色调的网站优秀的软文广告欣赏
  • 哈尔滨最好的网站建设公司什么网站可以发布广告
  • 图片网站怎么做排名沈阳今天刚刚发生的新闻
  • 一般做外贸上什么网站百度竞价托管费用
  • 做公司的网站有哪些东西吗昆明seo关键字推广
  • 静态网站什么样企业网络营销推广方案策划范文
  • 晋江哪里可以学建设网站自媒体135的网站是多少
  • 网站404页面怎么做浏览器2345网址导航下载安装
  • 自己做的网站二维码怎么做的百度云官网
  • 搭建php网站环境定西seo排名
  • 中企动力z云邮箱登录太原网站优化
  • 做视频怎样传到网站网站怎么优化推广
  • 网站设计背景图片怎么做的2022年新闻摘抄十条简短
  • 网站备案号在哪里关键帧
  • 网站全屏上下滚动谷歌优化师
  • 网站换公司吗关键词整站优化