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

营销型网站建设公司网络品牌营销方案

营销型网站建设公司,网络品牌营销方案,做网站难度大吗,石景山网站建设参考链接#xff1a; Java是否支持goto 开头先送大家一句话吧#xff1a; 众所周知#xff0c;在20世纪80年代早期#xff0c;C在贝尔实验室诞生了#xff0c;这是一门面向对象的语言#xff0c;但它又不是全新的面向对象的语言#xff0c;它是在传统的语言…参考链接 Java是否支持goto 开头先送大家一句话吧             众所周知在20世纪80年代早期C在贝尔实验室诞生了这是一门面向对象的语言但它又不是全新的面向对象的语言它是在传统的语言C语言进行面向对象扩展而来但是它有些地方与C语言又有很多区别又添加了很多C语言原来没有的内容与概念所以有些地方是需要花时间去深入了解的。虽然这两者有密切关系但是即使你很熟悉C语言想要熟悉C先不说熟练掌握或者精通C还是得花很大一番功夫光光是C之中的三大特性就够研究好久的了。所以说学习C的过程是一个漫长的过程如果将来从事和C或者说其它任何一门优秀的语言有关的工作那么对语言的学习可能会贯穿一生语言是一直发展而来的所以说要想成为一个优秀的程序员那么养成每天都学习一些新知识的习惯很重要我从来都觉得一个人的习惯很重要养成了每天学习的习惯那么有一天突然没有学习你会有一种今天有什么重要任务没有完成一样。但凡那些优秀的人从来都有一个好的习惯对于这一点我坚信不疑。好了其它的也不多说了千里之行始于足下。            对于C之中多态我准备分三个层次讲当然这是我我理解上的三个层次实际上这里面的内容远比我说的要多得多也更深得多我是由浅入深根据所需要的挑着看吧当然这里的深也只是相对的如果说C是一片海的话那我也只能说我只是见识过浅滩上的风景但是真正海底的神秘我还没有去研究希望将来有机会可以研究到如果只是单纯的想了解一下就没有必要整篇都看。前几天写了在C的学习过程中关于继承方面的一些知识今天就写一写关于剩下的特性多态封装性需要说的内容比较少所以就没有写  如果你只是想了解一下C之中关于多态的知识那么第一部分有你要的答案。如果你原本就对C之中多态有了解但是对是想了解内层的实现那么最后一部分会满足你的好奇心  在这里我盗用一下王国维先生对于读书三境界的总结来作为我每一层次的小标题。   按照我的习惯总是先从定义入手当然这第一层次肯定了解定义是必须的。首先来看一下多态的定义多态性的英文单词polymorphism来源于希腊词根poly(意为“很多”)和morph(意为“形态”意思是具有多种形式或形态的情形在C语言中多态有着更广泛的含义。在C之中多态的定义多态性是指具有不同功能的函数可以用同一个函数名这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性的向不同的对象发送同一个消息 不同的对象在接收时会产生不同的行为即方法。借用网上的一个牛人对于C之中多态总结的较好的三句话一、“相同函数名”二“依据上下文”三“实现却不同”。个人感觉这三句话总结地很到位在这里我就盗用一下。         既然这是第一层次所以在这里有必要先说一下关于C之中对象的类型先再看一张图  在了解了对象的类型之后有助于你更好地理解之后的内容。  好了说完定义之后我们肯定要来说一说多态的分类了还是以图的形式给出这样比较直观也便于大家去理解   接下来我们就来逐个分析一下  先来看一下静态多态编译器在编译期间完成的编译器根据函数实参的类型(可能会进行隐式类型转换)可推 断出要调用哪个函数如果有对应的函数就调用该函数否则出现编译错误。  其实我们在之前学C过程之中使用函数重载的时候就已经用到了多态只不过这是静态多态如果当时不知道可能你只是没有注意或者说没往多态这方面想而已。以下内容就是一个静态多态。   int My_Add(int left, int right) { return (left right); } float My_Add(float left, float right) { return (left right); } int main() { cout My_Add(10, 20) endl; cout My_Add(12.34f, 24.68f) endl; return 0; }        看完静态多态之后我们就来看一看动态多态在没有特殊说明的情况之下我们所说的多态一般都说的是动态多态。当然在说这个之前先知道什么时动态绑定在程序执行期间(非编译期)判断所引用对象的实际类型根据其实际类型调用相应的方法。        我们用一个例子来说明吧先看例子下面再来解释  class Airport                             //机场类 { public:            void GoToT1()           {  cout You want to T1 air terminal---Please Left endl;       //T1候机楼 }               void GotoT2()           {  cout You want to T2 air terminal---Please Right endl;      //T2候机楼 } }; class CPerson                            //人类 {  public:            virtual void GoToTerminal(Airport _terminal) 0;  }; class Passage_A :public CPerson          //乘客A类这类乘客需要去T1候机楼登机 {  public:            virtual void GoToTerminal(Airport _terminal) { _terminal.GoToT1(); } }; class Passage_B :public CPerson          //乘客B类这类乘客需要去T2候机楼登机 { public:            virtual void GoToTerminal(Airport _terminal) { _terminal.GotoT2(); } }; void FunTest()  { Airport terminal;                                //创建机场类对象 for (int iIdx 1; iIdx 10; iIdx)            { CPerson* pPerson;                     int iPerson rand() % iIdx;            //设置随机值这样可以使下面生成不同的子类对象        if (iPerson 0x01)                   {  pPerson new Passage_A;  } else                   {  pPerson new Passage_B; } pPerson-GoToTerminal(terminal); delete pPerson;                   pPerson NULL;                   Sleep(1000);                            //每次休息1秒后继续输出 } } int main() { FunTest(); return 0; }  在这里简单说明一下上面代码首先有一个机场类里面有两个方法表示两个候机楼在不同地方你需要左拐还是右拐。接下来就是一个人类里面只有一个纯虚函数因此这个人类就是一个抽象类。把这个抽象类作为基类又派生出两个子类。在子类之中把父类之中的纯虚函数重新定义了这也是必须的之前我在关于继承那一篇文章之中说过菱形继承之中就是利用虚拟继承解决数据二义性问题也就是说这里不存在二义性问题但是这里似乎更加具体直接在子类中把父类之中的虚函数带有virtual关键字修饰的函数重写了基类之中是一个纯虚函数派生类必须要重写它才可以实例化对象。  简单说一下重写或者说是覆盖两者意思一样如果两个成员函数处在不同的作用域之中上面的例子是一个在父类一个在子类父类之中有virtual关键字修饰这一点是必须的而且它们的的参数相同返回值类型也相同这里有必要说明一中特殊情况就是协变协变之中返回值类型可以不同那么这样的两个成员函数就构成了重写。派生类中的这个函数有没有virtual关键字修饰无所谓可加可以不加因为即使是派生类之中的这个函数它本质上也还是一个虚函数。  由于派生类之中对父类的纯虚函数进行了重写因此我们可以说上述代码实现了动态绑定。使用virtual关键字修饰函数时,指明该函数为虚函数在上面例子中为纯虚函数,派生类需要重新实现,编译器将实现动态绑定。 在使用对象的指针的时候要千万注意一下如下面的例子没有实现动态绑定。  int main()   {   Person  *p;   Man  *pm;   Woman *pw;   p man;     //如果你去调用其中的Man类中方法基类之中也有同名方法那么它会调用基类之中的方法 p woman;   //这是因为p的类型是一个基类的指针类型那么在p看来它指向的就是一个基类对象 //所以调用了基类函数。 } 最后看一下动态绑定的条件  1、必须是虚函数 2、通过基类类型的引用或者指针调用   到这里简单地总结一下动态多态动态多态性是在程序运行过程中才动态地确定操作所针对的对象。它又称运行时的多态性动态多态性是通过虚函数Virtual fiinction)实现的。其实到了这里对于多态这一块内容你已经有了初步的了解了如果你只是想初步了解一下已经足够了。但是可能还会有一些问题不过也影响不大毕竟只是初步认识一下至少你明白了多态的概念以及使用上的一些注意点。如果你想搞清楚更深一层的一些问题你可以继续阅读。  在这一层次上我们对虚函数纯虚函数作进一步了解动态绑定原理是什么然后进入一个大内容---虚表的概念。  在上一个内容上我们讨论过了关于动态绑定的概念这时候可能会有疑问动态绑定是如何实现的呢那么接下来我们就来说一说里面原理性的内容。   再解释之前我们还是先来理一理一些概念这样可以更容易理解里面的内容先做好准备工作。  首先是关于重载、重写也可以叫做覆盖、隐藏或者说是重定义这三者的有关内容如图所示  接下来我们再来说一说上面提到过的几个概念上面没有展开讲这里仔细讲一讲  纯虚函数   在成员函数的形参后面写上0则成员函数为纯虚函数。包含纯虚函数的类叫做抽象类也叫接口类抽象类不能实例化出对象虽然抽象类不能实例化对象但是可以定义抽像类的指针。纯虚函数在派生类中重新定义以后派生类才能实例化出对象。如下面代码中   class Person  {      virtual void Display () 0;   // 纯虚函数 protected :      string _name ;                 // 姓名 }; class Student : public Person  { //在这类里面必须要对上面的Display ()方法重新定义以后Student才可以实力化对象 }; 协  变  在C中只要原来的返回类型是指向类的指针或引用新的返回类型是指向派生类的指针或引用覆盖的方法就可以改变返回类型。这样的类型称为协变返回类型Covariant returns type)。如以下的两个函数就构成协变。当然协变也算一种覆盖。   class Base  {      Base * FunTest() { //do something } }; class Derived : public Base { pre namecode classcpp    Derived * FunTest() { //do something } };  有了上面这些铺垫之后我们就可以开始一个比较重要的内容关于虚表的相关知识。先来以下代码  class CTest { public:        CTest() {  iTest 10;  }        /*virtual */~CTest(){};  private:        int iTest;  }; int main()  {  cout sizeof(CTest) endl;        return 0;  }            很容易的得到结果是4但是如果将里面的注释内容也就是virtual关键字放开那么结果又会是多少呢知道的人会觉得这是送分题但是不知道的人却一脸茫然答案是8所以我们猜想一定是编译器对有virtual成员函数的类做了特殊处理。  先说个大概吧简单地说就是对于有虚函数的类编译器都会维护一张虚表对象的前四个字节就是指向虚表的指针。这也就可以解释为什么上面那个例子的原因了。  当然我们的问题才刚刚开始请仔细看下面一张图可能会解决你的一些疑惑  我们来分析一下上面的内容。我们在在监视窗口之中对对象test取地址发现虽然类中只有一个数据成员但是发现另一个内容其实它就是一个虚表指针观察它的类型发现它里面放着类似于地址的内容但是我们可以在内存之中去查看一下它的内容。内存之中虚表指针和数据成员是连着一起存放的所以这个虚表指针一定是有什么作用的。我们再打开一个内存窗口观察一下这个地址的所指向内容里面到底是什么。通过上面的图我们可以发现其实这里面放的还是一个地址突然间又有些疑惑了我们可以转到反汇编去看一看我们用virtual修饰的析构函数的入口地址就是刚刚我们看到的地址。在根据反汇编我们似乎就明白了什么。细心的你会发现其实每个虚表的最下面总是放的是0x00000000这也想相当于一个结束标志吧  这时候我们可以再来梳理一下其实_vfptr存放的内容就是存放函数地址的地址即_vfptr指向函数地址所在的内存空间我们可以用图来表示   到现在为止你对虚表以及虚表指针这些概念应该已经不陌生了来总结一下就是  test对象中维护了一个虚表指针虚表中存放着虚函数的地址。对test对象取地址可以看到的是虚表的指针以及它的其它成员变量这个对象又是如何调用类中虚函数的呢其实调用的虚函数是从虚表中查找的。如果基类中有多个虚函数的话那么虚表中也会依次按基类中虚函数定义顺序存放虚函数的地址并以0x 00 00 00 00 结尾。再如果子类中有自己定义的新的虚函数那么会排在虚函数表的后边。在调用虚函数时由编译器自动计算偏移取得相应的虚函数地址。  说到这里第二层次的内容主要也讲完了不过还有关于一些关于基类与派生类之间是如何利用这个虚表指针的以及如果函数之中存在覆盖或者说没有覆盖那么这虚函数表是否还是一样的呢我把放到下一个内容感兴趣的话可以接着往下看。      如果你坚持看了下来那么这一部分可能会有些复杂在这一部分主要是对虚表作进一步剖析也就是上面遗留下来的内容以及复杂一点的带有虚函数多继承对象模型剖析。  一个一个来说明首先是上面遗留的内容就是基类与派生类之间是如何利用这个虚表指针的呢其实这个内容还是需要分为两部分来讲一、基类与派生类不存在函数的覆盖二、基类与派生类之间存在函数的覆盖。  第一种情况比较简单在这里我主要用文字说明一下这样我们可以将重点放在第二种上面。   第一种情况不存在成员函数覆盖先调用基类构造函数虚表指针先指向基类虚表然后调用子类构造函数子类之中也有虚表指针而且不是同一个其实子类在构建起来之前的时候这个虚表指针指向的是基类的虚表但是当子类构建出来的时候虚表指针马上发生变化指向了一个新空间这个新空间里面存放了基类的虚函数以及派生类自己的虚函数在最后放入0x00000000子类自己的虚表也就构建完成了。这里说明一下1、虚函数按照其声明的顺序存在于虚表之中。2、在派生类的虚表之中前面是基类的虚函数后面是派生类的虚函数。  接着转入第二种存在成员函数覆盖以下面代码分析结合后面的图  class CBase  { public:            virtual void FunTest0() {  cout CBase::FunTest0() endl; }            virtual void FunTest1() { cout CBase::FunTest1() endl;  }            virtual void FunTest2() {  cout CBase::FunTest2() endl; }           virtual void FunTest3() {  cout CBase::FunTest3() endl;  }  }; class CDerived :public CBase  {  public:            virtual void FunTest0() {  cout CDerived::FunTest0() endl; }            virtual void FunTest1() {  cout CDerived::FunTest1() endl; }           virtual void FunTest4() {  cout CDerived::FunTest4() endl;  }            virtual void FunTest5() {  cout CDerived::FunTest5() endl;  }  }; typedef void(*_pFunTest)(); void FunTest() { CBase base;            for (int iIdx 0; iIdx 4; iIdx)           { _pFunTest  pFunTest (_pFunTest)(*((int*)*(int *)base iIdx));                   pFunTest(); } cout endl;           CDerived derived;            for (int iIdx 0; iIdx 6; iIdx)          {  _pFunTest  pFunTest (_pFunTest)(*((int*)*(int *)derived iIdx));                    pFunTest();  } } void TestVirtual()  {  CBase base0;          CDerived derived;           CBase base1 derived;  } int main()  { FunTest();          TestVirtual();           return 0;  } 说到这里大部分内容都已经结束了好了也是时候总结一下了  派生类重写基类的虚函数实现多态要求函数名、参数列表、返回值完全相同。(协变除外)基类中定义了虚函数在派生类中该函数始终保持虚函数的特性只有类的成员函数才能定义为虚函数静态成员函数不能定义为虚函数如果在类外定义虚函数只能在声明函数时加virtual关键字定义时不用加构造函数不能定义为虚函数虽然可以将operator定义为虚函数但最好不要这么做使用时容 易混淆不要在构造函数和析构函数中调用虚函数在构造函数和析构函数中对象是不完整的可能会 出现未定义的行为最好将基类的析构函数声明为虚函数。(析构函数比较特殊因为派生类的析构函数跟基类的析构 函数名称不一样但是构成覆盖这里编译器做了特殊处理)虚表是所有类对象实例共用的  还有一个关于多重继承之下的虚表指针的情况分析了这种情况就比较复杂了在这里同样也要分有无虚函数的覆盖这两种情况来分析。在这里我只简单地说一下有虚函数重载的情况有兴趣的下来可以自己去试一试。  class CBase0  {  public:           CBase0() { m_iTest 0xA0;  }           virtual void Print() {  cout m_iTest hex m_iTest   CBase2::Print() endl;  }           int m_iTest;  }; class CBase1  {  public:          CBase1() {  m_iTest 0xB0; }           virtual void Print() {  cout m_iTest hex m_iTest   CBase2::Print() endl;  }            int m_iTest;  }; class CBase2 { public:          CBase2() {  m_iTest 0xC0; }            virtual void Print() {  cout m_iTest hex m_iTest   CBase2::Print() endl;  }           int m_iTest; }; class CDerived :public CBase0, public CBase1, public CBase2  {  public:           CDerived() { m_iTest 0xD0;  }            virtual void Print() {  cout m_iTest hex m_iTest   CDerived::Print() endl;  }            int m_iTest;  }; void FunTest()  {  CDerived derived;           cout sizeof(derived) endl;           CBase0 base0 derived;           base0.Print();          CBase1 base1 derived;          base1.Print();           CBase2 base2 derived; base2.Print();          derived.Print(); } int main() { FunTest(); return 0; }             大家可以分析一下FunTest函数会打印什么以及Derived的内存布局是怎么样的呢我给大家一张图大家下来自行分析理解一下  其实如果你有兴趣还可以自己剖析下菱形虚拟继承不过肯定会有一些复杂。  写到这里说实话真的挺累的终于可以歇一歇了O(∩_∩)O在最后推荐大家一本书深度探索C对象模型这本书肯定是有一定难度的光听“深入”两个字就应该觉得有些挑战不过生活中还是应该多一些挑战。  最后再送大家一句话不忘初心方得始终
http://www.zqtcl.cn/news/873902/

相关文章:

  • 淘宝客网站建站源码icp备案查询官网入口
  • 环球资源网站网址微信管理中心
  • 青岛seo建站企业网址下载
  • 开发网站多少钱一个月做网站宽度
  • wordpress企业站主题哪个好做床上用品网站
  • 宜兴市做网站网站建设简讯
  • 点的排版设计网站音乐网站网页设计
  • 牛商网做网站的思路建设网站的机构
  • flash网站制作实例自适应网站做百度推广
  • 深圳建立网站电影里的做视频在线观看网站
  • 国家建设标准发布网站在哪里在线教育网站怎样建设
  • 徐州 商城网站设计winserver wordpress
  • 做网络课程的网站一般网站的架构
  • 网站建设包含哪些内容句容住房和城乡建设局网站
  • 做网站是做完给钱还是新房装修图片
  • 阿里云建站视频wordpress显示摘要插件
  • 济宁网站建设 企业谷网站开发有什么用
  • 网站建设一般多少钱官网代做网站公司哪家好
  • 页面简洁的网站深圳广告宣传片拍摄
  • 做外卖网站青岛助创网络科技有限公司
  • 怎么选择优秀的网站建设公司建设银行宁波分行 招聘网站
  • 工艺品网站模板下载-古色古香建站软件排名
  • 微视频网站源码网站建设目标个人博客dw
  • 山西省建设厅入晋备案网站洛阳网站在哪备案
  • 可以做物理试验的网站有哪些仿微博网站模板
  • 网站横幅怎做网站到期不想续费
  • 黑龙江网站备案管理局济南网站建设策划
  • 网站怎么静态化网页设计与制作图片显示不出来
  • 市场营销推广策划方案网站如何做标题优化
  • 怎么让客户做网站手机网站如何优化