深度探索C++对象模型(4)

2016-02-19 17:00 0 1 收藏

下面图老师小编跟大家分享一个简单易学的深度探索C++对象模型(4)教程,get新技能是需要行动的,喜欢的朋友赶紧收藏起来学习下吧!

【 tulaoshi.com - 编程语言 】

  雷神跌跌撞撞的读完了《深度探索C++对象模型》的第一章,虽然还是有些疑惑,但是已经感到收获很大。按照朋友的说法,第一章是一个概括的介绍,具体的细节会在以后的章节阐述,如果没有通读本书,第一章还是比较不容易理解的。雷神听过之后信心倍增,也不在有初看此书时的世界末日的感觉了(在第2篇雷神感到学了近一年的C++,居然水平如此之差),并且通过自己的努力,还是摸到了些门道,所以让我们继续快乐的出发,踏上深度探索C++对象模型的旅程。记住我们在第一篇的小文《坚持不懈,直到成功》,这可是获得成功的不二法门。

  第二章主要讲的的构造函数语意(Semantics),这是一个什么意思?我的英文和中文学的都不好,但我想是书上弄错了(也许只是一个笔误),也许应该翻译成语义比较恰当。The study or science of meaning in anguage forms. 语义学以语言形式表示意思的研究或科学。我们要研究构造函数的,并且以语言的形式将它描述清楚。

  看完题目我的第一个感觉,构造函数我知道。构造函数是一个类的成员函数,构造函数和析构函数是进行对象数据的创建,初始化,清除工作的成员函数,可以重载构造函数,使一个类不止具备一个构造函数,因有时需要以这些方法中的某一种分别创建不同的对象。不能重载析构函数。构造函数作为成员函数和类有相同的名字。例:一个类名为:aClass,构造函数就是aClass()。构造函数没有返回值,而且不能定义其返回类型,void也不行。析构函数同样使用这一点。当编写重载函数时,只有参数表不同,通过比较其参数个数或参数类型可以区分两个重载函数。但是我读完第一小段后就知道这一章要告诉我们什么了。

  这一章并不是要告诉我们什么是构造函数,它的作用是什么。而是要告诉我们的是构造函数是如何工作的。我的。在得知这点后我很兴奋,因为我确实不知道构造函数是如何构造一个类的对象的,并且一直想知道。我一直对面向对象神奇的功能很感兴趣。为什么一个类在被实例化时,可以自动的完成很多工作,使我们的主函数清晰,简单,稳健,高效。以前只看到了表面,没有深入,这会我们有机会去皮剔肉深入骨髓了。 书上主要讨论了几种情况:

  带有缺省构造函数的成员对象。如果一个类没有任何的构造函数,但他有一个成员对象,这个对象的类有一个缺省的构造函数,那么编译器会在需要的时候为这个类合成一个构造函数。

  举个例子:

  我们有以下几个类。它们都有一个构造函数。

  猫{public:猫(),......};

  狗{public:狗(),......};

  鸟{public:鸟(),......};

  鱼{public:鱼(),......};

  我们又有一个类。宠物,我们将猫作为它的成员之一。并且没有给它声明构造函数。

  宠物{

  public:

  猫 一只猫;

  狗 一只狗;

  鸟 一只鸟;

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  鱼 一只鱼;

  private:

  int ival;

  ......

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  }

  则当需要的时候编译器会为它合成一个构造函数,并且采用内联方式。大概象下面的样子。

  inline

  宠物::宠物()

  {

  猫.猫::猫();

  狗.狗::狗();

  鸟.鸟::鸟();

  鱼.鱼::鱼();

  ival=0;

  }

  为什么会这样,我们来看看编译器的行动。编译器开始执行用户的代码,准备生成宠物对象之前,会首先调用必要的构造函数,来初始化类的成员,以便为对象分配合适的内存空间。结果编译器会合成上面的构造函数,如果程序员为宠物类写了一个构造函数。 宠物::宠物(){ival=0;}那编译器也会将这个构造函数扩张成上面的那样。编译器是怎样实现的呢?原来当一个类没有任何用户定义的构造函数,而是由编译器自动生成的话,则这个被暗中生成的构造函数将会是一个没有什么用处的构造函数。但是通过编译器的工作能够为我们合成一个nontrivial default constructor.

  好象香港电影中演的,如果你惹上官司(你要设计一个类),你又没有钱去请高级的律师(没有给出构造函数),那会给你分配一个律师(缺省的构造函数),当然这个律师的能力也许和那些大律师比起来有差距(trivial)。不过我们要知道他们也不是一点用都没有。但是由于有律师行的督导,可以使这些律师能够努力做到最好(nontrivial)。

  同样的道理,我们可以理解另外的几种nontrivial default constructor的情况。

  如果你的类没有任何的构造函数,并且它派生于一个有着缺省构造函数的基类,那这个派生类的缺省构造函数会被视为nontrivial,因此需要被合成出来,他的合成步骤是调用上一层基类的缺省构造函数,并根据它们的声明次序为派生类合成一个构造函数。

  如果类声明或继承了一个虚函数,或者类派生于一个继承串链,其中有一个或更多的虚拟基类。由于缺少使用者声明的构造函数,则编译器会合成一个缺省的构造函数,以便正确的初始化每一个类对象的vptr。

  最后说一点,在合成的缺省构造函数中,只有基类的子对象和类的成员对象会被初始化,所有其他的非静态数据成员都不会被初始化,因为这些操作是需要程序员来做的。编译器没有必要连这些工作都做了。 好了,这篇就写到这里吧。这本书真的是雷神所看过的书中,看的最慢的一本了。但这些深层的知识有必要了解的很清楚吗,我们不知道编译器如何合成缺省的构造函数不也能写程序吗?雷神用侯大师的话来回答这个问题:练从难处练,用从易处用。知其然而不知其所以然,不是一个严谨的学习态度。

来源:https://www.tulaoshi.com/n/20160219/1613847.html

延伸阅读
关于《深度探索C++对象模型》停顿了半个月,今天继续啃这个骨头,我的学习进入了第四章,函数的语意学。先做个复习C++支持三种成员函数:静态、虚、和非静态。每一种函数的调用方式都不同,当然他们的作用也会有区别,一般来说我们只要掌握根据我们的需要正确的使用这三种类型的成员函数便可以了,至于内部是如何运做的我们可以不知。但是...
标签: PHP
  除了限制访问,访问方式也决定哪个方法将被子类调用或哪个属性将被子类访问. 函数调用与函数本身的关联,以及成员访问与变量内存地址间的关系,称为绑定。 在计算机语言中有两种主要的绑定方式—静态绑定和动态绑定。静态绑定发生于数据结构和数据结构间,程序执行之前. 静态绑定发生于编译期, 因此不能利用任何运行期的信息...
标签: PHP
  面向对象编程被设计来为大型软件项目提供解决方案,尤其是多人合作的项目. 当源代码增长到一万行甚至更多的时候,每一个更动都可能导致不希望的副作用. 这种情况发生于模块间结成秘密联盟的时候,就像第一次世界大战前的欧洲。 //haohappy注:喻指模块间的关联度过高,相互依赖性太强.更动一个模块导致其它模块也必须跟着更动。 ...
标签: PHP
  PHP5的访问方式允许限制对类成员的访问。这是在PHP5中新增的功能,但在许多面向对象语言中都早已存在。有了访问方式,才能开发一个可靠的面向对象应用程序,并且构建可重用的面向对象类库。 像C++和Java一样,PHP有三种访问方式:public,private和protected. 对于一个类成员的访问方式,可以是其中之一. 如果你没有指明访问方...
Photoshop选区深度探索-抽出对象   6.4 抽出对象 有些人喜欢使用[抽出]工具,可我不喜欢。如果已经掌握了前面所讲的全部选择工具,基本上能够制作出比[抽出]工具更好(更快)的图像效果。在剪取复杂的对象时,除了可以使用通道蒙版外,也可以使用[抽出]工具。 在详尽讲解[抽出]工具之前,先来谈一下它的基本操作步骤。请您在...

经验教程

661

收藏

6
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部