More Exceptional C++中文版试读(继承与多态)

More Exceptional C++ 读书笔记 More Exceptional C++ 读书笔记 Item 1 Switching Streams (1): 多考虑易读性,避免编写过渡简洁但是不易懂,不易维护的代码;    记个相当简洁的流切换代码:  (argc > 2 ? ofstream(argv[2], ios::out|ios::binary) : cout ) 1 ? ifstream(argv[1],      ios 阅读详情
[Herb Sutter 的名作More Exceptional C++中文版即将出版。作为本书译者,我很高兴将本书推荐给大家。征得华中科技大学出版社同意,我将公开部分译稿,敬请大家批评指正。] 

 

  

继承与多态

 

 

 

不来点继承和多态,面向对象将会怎样?

 

尽管继承常被滥用,但它还是一种很重要的工具——这包括多继承。特别是,当你生活在现实世界中时,你会发现,你经常需要将不同供货商提供的程序库结合起来使用,此时,多继承便凸显它的价值。本章向你展示,在结合使用不同供货商提供的“基于继承”的程序库时,应当如何避免连体双婴(Siamese Twin)问题。此外,本章还示范了许多合理(以及一些不合理地)使用纯虚函数的方式,以及如何编写多继承的替代方案、如何对使用继承关系的用户施加控制。

 

 

条款24:为什么要使用多继承?

难度:6

一些语言,包括SQL99标准,还在为“是否应该支持单继承或多继承”的问题大伤脑筋。本条款邀请您讨论这一主题。

 

1. 什么是多继承(MI,即multiple inheritance)?在C++中引入MI带来了哪些额外的可能性和复杂性?

 

2. MI究竟有必要吗?如果必要,尽可能多地列举出它的使用场合,并论证为什么应该将MI加入到语言中;如果不必要,请论证为什么单继承(SI)(并且,可能结合Java风格的接口)可以取代多继承、甚至比它更出色,以及为什么不应该将MI加入到语言中。

 

解答

 

1. 什么是多继承(MI,即multiple inheritance)?在C++中引入MI带来了哪些额外的可能性和复杂性?


非常简要地回答:MI指的是从多个(多于一个)直接基类(direct class)继承的能力。

 

例如:

 

    class Derived : public Base1, private Base2

    {

      //...

    };

 

在C++中引入MI所带来的可能性是:一个类的同一个(直接或间接)基类(base class)可能会不只一次地作为它的基础类(ancestor)出现。这里有一个简单的例子,即那个经典的钻石形状的继承图,如图4所示。

 

这里,B两次作为D的间接基类(indirect class)出现,一次是通过C1,另一次则是通过C2。

 

这种情况下,就很有必要引入C++的另一个特性:虚拟继承。现在的问题是:程序员希望D拥有基类B的一个子对象还是两个?如果答案是一个,B就应该是一个虚拟基类,图4就成为了可怕的死亡钻石。如果答案是两个,B就应该是一个普通(非虚拟)基类。

 

最后,虚拟基类的主要复杂性在于:它们必须通过最底层的派生类(most-derived class)直接初始化。关于这一点的详细介绍,以及MI其它方面的知识,请参阅[stroustrup00],或[Meyers97]条款43。

 

B

D

C1

C2

 

 

 

 

 

 

 

 

 

 

 


图4:可怕的死亡钻石(如果D从B虚拟继承)

 

 


 

设计准则

避免多继承自多个“非protocol类”。(protocol类是一种抽象基类(abstract base class),或简称ABC,它完全由纯虚函数组成,没有数据成员。)

 

2. MI究竟必要吗?

 

简短的回答是:只要程序可以用汇编语言(或更低级的语言)来写,就不能说某种特性绝对“必要”。然而,正如大多数人不会去用简单的C编写自己的虚函数机制一样,在某些场合下,没有MI会让你大费周章。

正因为如此,我们现在才有了这一被称为MI的神奇特性。但问题是——或者,至少前面的问题应该换为——MI是个好东西吗?1

简而言之,的确有人认为MI是个坏主意,因而无论如何都应该避免它。这不对。是的,如果你在使用MI时有欠考虑,它的确会招致不必要的耦合性和复杂性。然而,任何一种被误用的继承都是这样(参见Exceptional C++ [Sutter00]条款24),但我相信,大家不会就此认为继承不是个好东西。还有,是的,在完全不使用MI的情况下,任何程序都可以写出来,但你也得知道,在完全不使用继承的情况下,任何程序也都可以写出来。实际上,任何程序都可以用汇编语言来写。但这并不是说用汇编语言来写程序就一定是个好主意,相反,你甚至不愿意去做那样的事。

2.如果必要,尽可能多地列举出它的使用场合,并论证为什么应该将MI加入到语言中;如果不必要,请论证为什么单继承(SI)(并且,可能结合Java风格的接口)可以取代多继承、甚至比它更出色,以及为什么不应该将MI加入到语言中。

 

那么,什么时候使用MI才算合适?简而言之,只有在每一个继承单独取出来看都合适的时候,这样的MI才算合适。Exceptional C++条款24提供了一个相当详尽的列表,说明了什么时候该使用继承。在现实世界中,MI的应用大多逃不出以下三类。

1. 结合使用程序模块或程序库。之所以首先提出这一点有一个理由,我将在后面说明。很多类被设计为基类——即,在使用时你得从它继承。这很自然地带来一个问题:如果你想写一个类,它用到了两个程序库,但每个程序库都要求你从它的某个类继承,这时候你该怎么办?

__________________

1. 一定程度上,本条款的主题启发自1998年6月SQL标准会议上发生的事件,在那次会议中,多继承被从ANSI SQL99标准草案中删除了。(如果说得远一点的话,你们当中如果有人对数据库感兴趣,就会知道,在SQL4中MI又以修订形式重新恢复了。)当时之所以那样做,主要是因为所提出的多继承规范存在技术上的困难,并且是为了想和Java这些不真正支持多继承的语言看齐。另外,仅仅是坐在那儿听人们在那样一个相对太迟的时间里争论多继承的优缺点,这本身就让人觉得有趣。在C++世界中,自这种语言形成以来,我们很少做这种事;这让我回忆起几年前(或比这更近的时期)新闻组上广泛展开的激烈争论,我会忍不住自言自语地念出一些标题,譬如:“MI是罪恶!!!”


在面对这种情况时,你一般无法通过修改程序库代码来避免某个继承。因为,它可能是从第三方供货商购买的程序库,或者,可能是你的公司里另一个项目组开发的模块。无论哪种情况,你不但不能修改代码,你甚至可能没有代码!如果是这样,MI就是必要的;没有其它(自然的)方法可以帮助你去做你必须做的事;此时,使用MI完全合理。

 

在实践中我发现,知道如何运用MI来结合使用供应商提供的程序库,这是每一个C++程序员必须具备的素质。无论你是否经常运用它,你绝对应该知道它并理解它。

 

2. Protocol类(interface类)。在C++中,MI最合适、最安全的应用是定义protocol 类——即,完全由纯虚函数构成的类。由于这种基类没有数据成员,MI臭名昭著的复杂性就得以完全避免。

 

有趣的是,有的语言(或模型)通过非继承机制来支持这种MI。Java和COM就是两个例子。严格来说,Java有多继承,但它将实现(implementation)的继承仅限于单继承。一个Java类可以实现多个“接口”,这种接口非常类似C++中没有数据成员的纯抽象基类。COM本身没有继承的概念(虽然在用C++来写COM对象时,这是一种常用的实现技术),但它同样也有“接口组合(composition of inerfaces)”的思想,COM接口类似Java接口和C++模板的结合。

 

3. 易于(多态)使用。有了继承,在接受基类对象的任何代码中,我们就都可以使用派生对象,这是一项威力强大的功能。在某些场合,如果同一个派生对象可以代替数种基类对象使用,那将会很有用处,这正是MI大显身手的地方。关于这一点有一个好例子,请参阅[Stroustrup00]14.2.2节,那里演示了一个基于MI的设计,用以构造异常类(exception class);在那个设计中,最底层的派生异常类可能和多个直接基类具有多态式的Is-A关系。

 

注意,第3点在很大程度上与第1、2点重叠。在实施另两点之一时,同时、并出于相同的理由运用第3点,往往很有用处。

 

还要考虑到另一点,不要忘记:有时候,单纯从两个不同的基类继承并没有必要,相反,我们要让每一个继承都有不同的理由。“多态的LSP Is-A 公有继承”并非唯一故事(译注:参见条款23);使用继承还有很多其它可能的原因。例如,一个类可能需要从一个基类A私有继承,以获得对类A的保护成员的访问权,同时,它还要从另一个基类B公有继承,以多态地实现类B的某个虚函数。

More Exceptional C++中文版:高级C++编程进阶实战指南 异常处理从来不是一个孤立的话题。它与 RAII、模板、设计模式、编译器优化紧密交织在一起。真正厉害的程序员,不是靠“避开异常”来写出稳定代码,而是利用异常机制本身去构建更可靠的系统。就像汽车的安全气囊,你不希望它弹出来,但一旦需要,它必须起作用。这种高度集成的设计思路,正引领着现代 C++ 向更可靠、更高效的方向演进。🚀本文还有配套的精品资源,点击获取。 阅读详情

相关推荐

Exceptional C++(中文版)和More Exceptional C++(中、英文版)

Exceptional C++(中文版)和More Exceptional C++(中、英文版)

More_Exceptional_C++(中文)pdf

下载地址:网盘下载 More Exceptional C++是Exceptional C++的续篇。根据多年程序开发的实践经验、Herb Sutter向C++程序员提供了久经考验的程序设计技术和行之有效的解决方案,这些技术和方案对设计从小型工程到企业级应用的现代软件系统大有裨益。 围绕着40个编程难题, More Exceptional C++引...

weixin_30571465的博客 1115

Exceptional.C++

Exceptional.C++中文

xx读书笔记

在本书中,Herb Sutter采用了独具匠心的“提问/解答”的方式来指导你学习C++的语言特性;在本书的每个专题中,HerbSutter合理地设想出你的疑问和困惑,又有如神助地猜到了你的(可能是错误的)解答,然后给你以指点并呈现出最佳方案,最后,还提炼解决类似问题的一般性原则。 本书适合的读者对象是中高级程序员,尽管如此,只要具备基本的C++功底和一定的程序设计经验,你完全可以理解和消化本书的

backard的专栏 643

[计算机科学经典著作].Addison.Wesley.-.More.Exceptional.C++.pdf

[计算机科学经典著作].Addison.Wesley.-.More.Exceptional.C++.pdf

More.Exceptional.C.:40个新的工程难题、编程疑问及解决方法

随着对泛型程序设计和C++标准库有关话题的深入研究,我们还会碰到更多的问题。这本书就是一个答疑的地方。

more exceptional c++读书笔记

Part1 我是在读完Scott Meyers的《Effective c++》之后才读到这本书的。能够讨论特定的主题而不是将一门语言作为一个整体来看待是我理解c++的首选方式,所以Sutter和Meyers的书非常适合我。 与Meyers系列相比,exception c++系列的主要优势在于,您可以告诉Sutter是更好的程序员。你可以相信Meyers 所说的一切都是正确的,但最终你真正得到的只是一些关于如何做某些事情的额外指示。另一方面,Sutter在同样的主题上讲得更深入一些,让你觉得自己可以写出更

itaoest的博客 413

more exceptional c++中文版

more exceptional c++中文版

More Exceptional C++ 中文版试读(译序及目录)

 [Herb Sutter 的名作More Exceptional C++中文版即将出版。作为本书译者,我很高兴将本书推荐给大家。征得华中科技大学出版社同意,我将公开部分译稿,敬请大家批评指正。]  与大师面对面(译序)  小提琴家穆特录制过一张唱片,收录的是贝多芬最伟大的两部小提琴作品1。聆听那张唱片,你仿佛听见贝多芬在向你倾诉他对音乐艺术的理解和感悟、为你解答小提琴音乐创作

lostmouse的专栏 1803

exceptional c++ 与 more exceptional c++ 英文版

英文版 C++经典书籍 英文版看了也还行,主要是能锻炼自己,豆瓣评分8.4 加油

More Exceptional c 与大师对话 pdf版.rar

More.Exceptional.c .pdf 与大师对话,讲解泛型程序设计与C 标准库、优化与性能、异常安全议题及技术、继承与多态、自由函数与宏、杂项议题、后记等内容。

More Exceptional C++起步于Exceptional C++驻足之处

古希腊哲学家苏格拉底通过向学生提问进行教学——他用那些精心构思的问题来指导学生,启发他们从已知得出结论;让他们认识到自己正在学习的事物如何相互联系,这些事物与他们已有的知识又如何联系。这种教学法如此出名,以致于我们今天把它专称为“苏格拉底问答法”。如果让我们也从学生的角度来看问题,苏格拉底的教学法将引导我们,促使我们思考,帮助我们联系并应用现有的知识去获取新知。 本书如同它的前任Exceptional C++ [Sutter00]一样,借鉴了苏格拉底的教学法。它假设你目前正身处C++产品软件开发的某个领域

博文视点(北京)官方博客 1339

5分钟搞定!用Coze+剪映小助手批量生成萌宠视频(附完整工作流配置)

本文详细介绍了如何利用Coze工作流与剪映小助手快速批量生成萌宠视频的完整方案。通过智能内容生成、素材处理、剪辑组装和输出适配四大模块的协同,实现5分钟内完成高质量视频制作。特别适合多宠物账号运营者,工作流支持模板切换和参数修改,大幅提升内容生产效率。

weixin_28678151的博客 392

C++ 为何如此强大?

在31年前(1979年),一名刚获得博士学位的研究员,为了开发一个软件项目发明了一门新编程语言,该研究员名为Bjarne Stroustrup,该门语言则命名为——C with classes,四年后改称为C++。

weixin_53644828的博客 289

vscode运行.ipynb代码时提示需要安装ipykernel包的解决办法

此文目的是为了记录遇到的一些问题,也希望能帮助到和我一样遇到困难的同学。如需转载,请注明出处。在使用vscode运行.ipynb文件中提示需要安装ipykernel包的提示,在网上查询了很多方法之后也是终于解决了问题。写下这篇博客也希望能帮到大家。

qq_58018041的博客 4万+

西门子博途系列学习笔记SCL(三)______自由口通讯(RS485轮询程序)

西门子博途V16系列学习笔记SCL(三)___自由口通讯轮询程序(RS485) 西门子博途系列学习笔记SCL(三)______自由口通讯(RS485轮询程序) 文章目录西门子博途V16系列学习笔记SCL(三)___自由口通讯轮询程序(RS485)前言一、FreePort自由口通讯是什么?二、使用步骤1.模块参数定义2.定义FB功能块参数:3.程序代码如下(每天写代码100行,学不会你来找我):总结 前言 很长时间都没有更新了,主要是最近在学习罗克韦尔的STUDIO5000PLC编程软件,怎么说,和博

weixin_42940283的博客 1万+

读书笔记之:More Exceptional C++ (2002) [++]

1. std::cin和std::cout的类型是什么? 简单的回答,cin实际上是: std::basic_istream<char,std::char_traits<char>> cout实际上是: std::basic_ostream<char,std::char_traits<char>> 首先,cin和cout具有的类型...

weixin_33957648的博客 129

1、JMP脚本编程全面指南:从基础到高级应用

本博客全面介绍了JMP脚本编程的各个方面,从JMP基础和JSL入门,到数据类型、数据结构、编程方法、数据表操作、图形与三维场景脚本,再到应用程序创建与扩展功能。内容涵盖脚本工具使用、常见任务实现、兼容性说明及未来发展趋势,旨在帮助用户掌握JMP脚本语言的强大功能,提升数据分析的自动化与定制化能力。适合从初学者到高级用户的深入学习与实践参考。

flink9streamer的博客 267

《More Exceptional C++:40个新的工程难题、编程疑问及解决方法》(中文版)

《More Exceptional C++:40个新的工程难题、编程疑问及解决方法》(中文版)china-pub预订中 推荐语: 本书针对一定的主题,为程序员提供了简明扼要的指导,从而将学习时间和疑惑减至最少。本书内容包括泛型程序设计与c++标准库、优化与性能、异常安全议题及技术、继承与多态、内存及资源管理、自由函数与宏等。 本书内容全面丰富,论述翔实清晰,作者权威且经验丰富,是c++程序员...

yangzhiyong77 297

SpringBoot4.0+JDK25+GraalVM实战:云原生新纪元,微服务性能翻倍的落地指南

三者的组合不是偶然,而是“框架优化+JDK升级+虚拟机革新”的必然结果——SpringBoot4.0完善了对GraalVM原生镜像的支持,JDK25强化了云原生与AOT编译能力,GraalVM则提供了极致的启动速度和资源利用率,三者协同,刚好命中云原生微服务的核心痛点。SpringBoot4.0+JDK25+GraalVM的组合,不是简单的版本升级,而是云原生微服务的一次性能革命。

2601_94871597的博客 1142

SAP-MM-采购过账接口(与WMS集成)-代码

1、判断传入值非空检验; 2、判断过账日期是否允许在当前期间; 3、判断是否为集采订单业务,是否审批完成; 4、判断是否发布标准成本发布(此业务场景与价格控制3+S有关) 5、保存日志表; 6、判断业务公司订单审批状态; 7、创建STO交货单、集采公司订单过账、STO公司间创建交货单、交货单过账(两步法)、过账失败回滚(冲销交货、删除交货单、冲销集采入库)

qq_32198063的博客 421

海康威视错误代码说明(六)(错误代码:82~825)

海康威视错误代码说明 6 错误代码及说明 网络通讯库错误码 (82~825) 错误名称 错误值 说明 NET_DVR_PARAVERSION_ERROR 82 导入参数时软件版本不匹配。 NET_DVR_IPCHAN_NOTALIVE 83 预览时外接 IP 通道不在线。 NET_DVR_RTSP_SDK_ERROR 84 加载标准协议通讯库 StreamTransCli...

二等碗 1万+

【STK】手把手教你利用STK进行弹道导弹和运载火箭发射仿真的相关方法全过程解析

写这个系列主要是这几年做了一些弹道导弹和运载火箭发射的相关仿真项目,stk软件由于其专业性在国内比较小众,相关的教程和书籍、经验贴都不是很多,因此新手在进行开发中容易遇到较多困难,把自己的一些经验体会写下来,一方面供自己总结回顾,另一方面也希望对大家有所帮助。这个系列计划分几篇文章写完,每章的内容结构相似,都分为①如何确定发射场位置和发射轨迹、②导入导弹和运载火箭模型、③设计模型分段动作、④飞行参数分析和相关应用这四个部分,每篇文章争取完整描述1-2个实际项目的操作过程。

weixin_44184852的博客 5988

合上More Exceptional C++的瞬间

与大师面对面(译序) 小提琴家穆特录制过一张唱片,收录的是贝多芬最伟大的两部小提琴作品 。聆听那张唱片,你仿佛听见贝多芬在向你倾诉他对音乐艺术的理解和感悟,为你解答小提琴音乐创作的每一个疑问和困惑。为了向音乐爱好者推荐贝多芬的那两部名作,穆特为她的那张名碟加上了一个恰如其分的标题—— “与贝多芬面对面”。 合上More Exceptional C++的瞬间,我的第一反应是为这本名著也加上一个与之类似的副标题,然后,郑重地推荐给你。 是的,本书奉献给你的是又一位大师苦心孤诣的结晶。不同的是,这位大师来自

博文视点(北京)官方博客 1404

ardupilot开发 --- Remote ID 篇

适配ardupilot的Remote ID模块研发,远程标识模块研发。Remote ID模块可以通过蓝牙或wifi向外广播无人机的状态信息、位置信息、任务信息等,并可以通过蜂窝数据向国家无人驾驶航空器一体化综合监管服务平台上报这些信息。Remote ID功能是21年起国家出台的民用无人机适航飞行的基本要求!

记录老板的每次pua,分享领导每天的毒鸡汤... 9608

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: More Exceptional C++ 中文版试读(译序及目录)
下一篇: More Exceptional C++中文版试读(异常安全议题及技术)
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值