C++从零开始(中)——类的相关知识.pdfVIP

  1. 1、本文档共2页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C从零开始(中)——类的相关知识,从零开始学习股票知识,从零开始作品相关,英语基础知识从零开始,从零开始学中医,类似从零开始的小说,类似从零开始的穿越女,从零开始学中医pdf,消防中队学习从零开始,从零开始练瑜伽

C++从零开始(中)——类的相关知识 本文关于虚函数的论述有一处严重错误,关于此错误已在本文的评论中说明,对此造成的不 便,在此深感抱歉。 由于篇幅限制,本篇为《C++从零开始(十一)》的中篇,说明多重继承、虚继承和虚函 数的实现方式。 多重继承 这里有个有趣的问题,如下: structA {long a,b,c;chard;};structB : public A {long e,f;}; 上面的B::e 和B::f 映射的偏移是多少?不同的编译器有不同的映射结果,对于派生的 实现,C++并没有强行规定。大多数编译器都是让B::e 映射的偏移值为16(即A的长度, 关于自定义类型的长度可参考《C++从零开始(九)》),B::f映射20。这相当于先把空间留 出来排列父类的成员变量,再排列自己的成员变量。但是存在这样的语义--西红柿即是蔬菜 又是水果,鲸鱼即是海洋生物又是脯乳动物。即一个实例既是这种类型又是那种类型,对于 此,C++提供了多重派生或称多重继承,用“,”间隔各父类,如下: structA {longA_a,A_b,c;voidABC(); };structB { long c,B_b, B_a; voidABC ();}; structAB : public A, public B { long ab,c;voidABCD(); }; void A::ABC(){A_a =A_b =10;c =20; } void B::ABC() {B_a = B_b =20;c =10; } void AB::ABCD() {A_a =B_a = 1;A_b =B_b = 2;c =A::c =B::c =3; } void main() {AB ab;ab.A_a =3;ab.B_b =4; ab.ABC();} 上面的结构AB 从结构A和结构B 派生而来,即我们可以说ab 既是A 的实例也是B 的实例,并且还是AB 的实例。那么在派生AB 时,将生成几个映射元素?照前篇的说法, 除了AB 的类型定义符“{}”中定义的AB::ab 和AB::c 以外(类型均为long AB::),还要生成 继承 来的映射元素,各映射元素名字的修饰换成AB::,类型不变,映射的值也不变。因此 对于两个父类,则生成8个映射元素(每个类都有4个映射元素),比如其中一个的名字为 AB::A_b,类型为 longA::,映射的值为4;也有一个名字为AB::B_b,类型为long B::,映 射的值依旧为4。注意A::ABC 和B::ABC 的名字一样,因此其中两个映射元素的名字都为 AB::ABC,但类型则一个为void( A:: )()一个为void( B:: )(),映射的地址分别为A::ABC 和 B::ABC。同样,就有三个映射元素的名字都为AB::c,类型则分别为long A::、long B::和long AB::,映射的偏移值依次为8、0 和28。照前面说的先排列父类的成员变量再排列子类的成 员变量,因此类型为long AB::的AB::c 映射的值为两个父类的长度之和再加上AB::ab 所带 来的偏移。 注意问题,上面继承生成的8 个映射元素中有两对同名,但不存在任何问题,因为它们 的类型不同,而最后编译器将根据它们各自的类型而修改它们的名字以形成符号,这样连接 时将不会发生重定义问题,但带来其他问题。ab.ABC();一定是ab.AB::ABC();的简写,因为 ab 是AB 类型的,但现在由于有两个AB::ABC,因此上面直接书写ab.ABC 将报错,因为 无法知道是要哪个AB::ABC,这时怎么办? 回想本文上篇提到的公共、保护、私有继承,其中说过,公共就表示外界可以将子类的 实例当作父类的实例来看待。即所有需要用到父类实例的地方,如果是子类实例,且它们之 间是公共继承的关系,则编译器将会进行隐式类型转换将子类实例转换成父类实例。因此上 面的ab.A_a = 3;实际是ab.AB::A_a = 3;,而AB::A_a 的类型是long A::,而成员操作符要求 两边所属的类型相同,左边类型为AB,且AB 为A 的子类,因此编译器将自动进行隐式类 型转换,将AB 的实例变成A 的实例,然后再计算成员操作符。 注意前面说AB::A_b 和AB::B_b 的偏移值都为4,则ab.A_b =3;岂不是等效于ab.B_b = 3;?即使按照上面的说法,由于 AB::

文档评论(0)

tianma2015 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档