- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
动态约束的实现 优化实现模型,其中绝大部分工作都能静态完成: 每个类的运行时体现是一个动态约束方法的表(称为虚表,vtable),这是一个指针表,指针指向本类的对象需要调用的方法的代码体 虚表的指针按方法在类里的顺序排列,每个方法对应于一个顺序下标 动态约束的实现 在每个对象开头(数据域之前)增加一个指针?vt 创建对象时,设置其?vt?指向其所属的类的虚表(运行中始终不变) f?是指向?F?的指针(或引用)调用?f-m(...)的实现 比调用静态约束的方法多了中间的两条指令,它们都需要访问内存 动态约束的实现 虚表的创建: 如果类?B?没有基类,就将其定义里的动态约束方法的代码体指针依次填入它的虚表(下标从?0?或者?1?开始算) 若类?D?的基类是?B,建立?D?的虚表时先复制?B?的虚表。如?D?覆盖了?B?的某个(某些)动态约束方法,就用新方法的指针覆盖虚表里对应的已有指针。若?D?定义了新的动态约束方法,就将它们顺次加入虚表,放在后面 如果?f?指向的对象是?B,那么?f-m(...)?也会调用正确的方法 动态约束的实现 重温受限的对象模型(对一般程序设计已经足够强大)?:? ·??类层次结构是静态确定的? ·??每个类里的动态约束方法的个数和顺序都静态确定 ? 优化实现的效果:? ·??构造方法表的工作在编译时完成? ·??每个对象里需要增加一个指向其类的方法表的指针? ·??每次方法调用需要多执行两条指令(典型情况),多访问内存两次 对这种受限对象模型,动态约束方法调用的额外开销不大,一般软件系统(包括系统软件的绝大部分情况)都可以接受 Stroustrup?在设计和实现?C++?语言时特别希望能够得到高效的实现,最后选择了这种对象模型,并设计了这种高效的实现方法 动态约束的实现 对数据抽象和面向对象技术的支持,以及高效的实现,使实际软件工作者看到了?C++(和?OO)的潜力,最终导致了面向对象的革命 以后的主流面向对象语言也都采用了这种技术。当然,采用这种选择,也就对它们可能采用的对象模型提出了严格的限制 Pragmatics?里还讨论了其他高效实现方法,《C++?语言的设计与演化》里也有讨论(通过几条指令构成的一段“蹦床代码”,将控制转到实际应该调用的方法,主要是要解决多重继承问题) 虚方法(动态约束方法)的一个重要缺点是不能做?inline?处理(在线展开要求静态确定被调用的方法),使编译器难以进行跨过程的代码优化 C++?希望支持高效的系统程序设计,认为虚方法带来的效率损失有时也是不能容忍的,因此它同时支持静态方法约束 注意:如果一个类里只有静态约束的方法,该类编译之后就不会生成方法表,该类的对象也没有一个指针的额外存储开销 类层次结构和强制转换 向上强制总是安全的,不会出问题,总可以自动进行。因为派生类包含基类所有数据成分,因此可以支持基类所有操作 后一个赋值是编译时错误,派生类指针不能引用基类对象 类层次结构和强制转换 如果用?foo?类的指针?q?传递一个对象 可保证该对象一定是?foo?的或它的某个派生类的对象? 如果由?foo?类指针?q?传递的实际上是一个?bar?对象,我们有时需要把它作为bar?对象使用,例如想对它调用?foo?里没有的方法 · q-s(..)?是静态类型错误(q?的指向类型是?foo,foo?无方法?s)? · s??=??q?也是静态类型错(不能保证?q?指向的是?bar,赋值不安全)? 能不能用?s??=??(bar*)q???? 如果?q?指向的确实是一个?bar?对象,当前情况下恰好可以,因为? ·??(bar*)?对指针是“非变换转换”,导致把?foo?指针当做?bar?指针? ·??恰好?bar?对象的起始位置和各成分的偏移量与?foo?一样 这些条件有时不成立(下面会看到,在存在多重继承时)? 这种转换不安全,它要求?q?指向的确实是?bar。动态怎么检查类型? 类层次结构和强制转换 C++?为安全的向下强制转换提供了专门运算符?dynamic_cast。上述转换的正确写法: bar??*x??=??dynamic_castbar*(q); 如果?q?指向的确实是?bar?类的对象,转换将成功,x?指向该?bar?类对象 如果?q?指向的不是?bar?类的对象,转换失败,x?被赋空指针值?0 通过检查?x?的值,可以判断转换是否成功 实现?dynamic_cast,就要求在运行中能判断对象的类型和类型间关系 这就是运行时类型识辨(Run?Time?Type?Identification,RTTI) ? 要像支持安全的向下转换,C++?的实现需要在?虚表里
原创力文档


文档评论(0)