这历来是一个受争议的话题,书上的样板话我就不说了。我只说说自己的一点观察和体会:

1. 多重继承在理论上是有道理,21天学通C++里举了一个例子,就是飞马继承于飞鸟(会飞)和马(会跑),你可以定义一个函数func1,使之有时候飞有时候跑(5公里以内跑,更远就飞),看上去两全其美,但如果既要飞又要跑呢?这样的自定义函数就解决不了问题了。非得多继承才行。总结:多继承理论上是有道理的。

2. 现实生活中,完全多继承的情况很少。比如人虽然继承自父母,但也只是继承了一部分功能,还得加上自己的某些基因突变,所有会有自己的脾气和其它特性,相反使用组合的情况非常多。总结:多继承的情况很少,也不实用。

3. 接口分担了多继承的大部分功能,使得多继承更加显得不那么必要。当然,接口没有实现相关的功能。如果想要直接使用别人已经实现的功能,仍然无法完成这个任务。但是可以在内部使用组合对象,使用一句话实现相关函数,就可以伪装成实现接口功能。总结:接口分担了相当一部分功能,估计这也是C++始终没有加入接口的原因,因为不需要嘛,有多继承和纯虚函数就已经达到了同样的目的,虽然不够优雅。另外要提一句的是,接口看上去更优雅。如果编译器支持的话(比如Delphi),可以自动释放内存,还可相互探测和转化,十分方便和强大。

4. 多继承虽然有道理,但是与生俱来带来了一些使用上的麻烦:菱形内存接口是很痛苦的,什么虚继承之类的烦不胜烦,我还有个疑惑是,谁能提前想到自己正在定义的类将来是要被虚继承的啊?如果没想到就不会提前加上关键字,就达不成虚继承的目的。让别人提起知道某些事情,就破坏了OO的好处。另外菱形布局对虚函数表也有影响,好像有多个虚函数表,这在侯捷翻译的《深入C++探索》一书有详细描述,我也只是看了一眼,以后再补充。总结:使用太麻烦,内部实现也相当复杂,虚继承似乎破坏了OO的纯洁性。

5. 今天在论坛上看到一个问题:“如何监控一个对象是否被析构”,回答多种多样:比如析构的时候发一个信号;如果不是实时需要,自己探测对象指针是否为NULL。但是有一个回复引起了我的注意:让所有子类都继承你的类,在那个类在析构的时候监控一下就好了。这句话立刻让我想到了C++多重继承的强大功能,这是我之前从未想到过的,而且这个功能强大到可以被滥用。

即:我让项目中所有的类全部继承我自己定义的某个类,也不会影响原来的类继承正常的别的类。这样就有利于项目的全局管理和控制,或者快速的给所有类加上某项强大功能。对于那些不支持多继承的语言就不行了(现实中好像只有C++支持多继承,不知道有没有别的语言也支持,欢迎补充),只能通过组合来实现,那样就要修改每一个类的内部实现,哪怕仅仅是在每个类里增加一句话也是够麻烦的,而且同样破坏了OO的纯洁性。这个功能很值得深思,而且不仅仅可以改写项目里的类,有空或许可以试试改写类库(比如MFC)里的类,使类库也被置于程序员的强大控制之下,这样一个强大的类,其作用甚至远远超过CObject和QObject。
总结:C++多继承很强大,强大到在不影响正常功能的情况下可以控制一切,强大到可以被滥用,有空一定要试试给全部类继承自己的类,看看能不能达到某种以前没有达到过的境界。

6. C++虽然没有接口,但却有纯虚类,这样就在一定程度上替代了接口的作用。如果使用纯虚类的指针,再加上多继承的强大功能,虽然不如纯接口那么优雅,但是也已经非常实用了。

7. 在理论上有一个把许多人绕晕的“虚继承”问题,其实在现实生活中几乎不存在,所以不必在意。看看在现代化重新设计的QT类库就知道了,大量用到了多继承,比如QWidget就是,不但没有思维上的干扰,反而非常实用和强大。如果出现要处理虚继承的情况,只能说这个类库的设计已经差到了极点。

----------------------------------------------------------------------------

我在求学的时候了解过一些开源库,比如说OggVorbis、7-zip以及github上的一些开源库,还有微软的DirectX库,COM组件等
其中了解了一些编程模式,
懂得了使用C++的一些特殊语法可以达到很多意想不到的效果,即使是C++98。
比如说刚刚那个就是COM的编程思想。

有道理,都是实用派的编程模式吧。
像什么《设计模式》这样的经典书里是不会讲到这个的。

C++多继承的观察和7点体会(都是实用派的观点) good的更多相关文章

  1. Qt 自定义事件(三种方法:继承QEvent,然后Send Post就都可以了,也可以覆盖customEvent函数,也可覆盖event()函数)

    Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展.在 Qt 中,你需要继承的类是 QEvent. 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定 ...

  2. objective-c自学总结(三)---面向对象的封装,继承与多态

    面向对象的三大特性 封装 继承 多态 1.封装: 隐藏属性,方法或实现细节的过程称为封装 信息隐藏,隐藏对象的实现细节,不允许用户看到 将东西包装在一 然后以新的完整形式呈现出来 例如,两种或多种化学 ...

  3. Swift学习笔记十三:继承

    一个类能够继承(inherit)还有一个类的方法(methods),属性(property)和其他特性 一.基本的语法 class Human{ var name :String init(){ na ...

  4. Day8 类的继承

    为什么要继承? 观察两个类的成员组成 提取相同的属性和方法 宠物是父类,狗和金鱼是子类.子类具有父类的属性和方法. 继承定义 是使用已存在的类作为基础建立新类的技术. 单一继承:只有一个父类. 父类可 ...

  5. swift学习笔记(四)关于类的继承

    在swift中,继承是区分类与其它对象的基本特征 继承后的子类能够重写父类的方法,包含类方法和实例方法,属性和附属脚本(subscript) 在继承过程中,构造器方法init()是不被继承的,须要显示 ...

  6. javascript中的继承与深度拷贝

    前言 本篇适合前端新人,下面开始...... 对于前端新手来说(比如博主),每当对js的对象做操作时,都是一种痛苦,原因就是在于对象的赋值是引用的传递,并非值的传递,虽然看上去后者赋值给了前者,他们就 ...

  7. 设计模式(七): 通过转接头来观察"适配器模式"(Adapter Pattern)

    在前面一篇博客中介绍了“命令模式”(Command Pattern),今天博客的主题是“适配器模式”(Adapter Pattern).适配器模式用处还是比较多的,如果你对“适配器模式”理解呢,那么自 ...

  8. (十四)Maven聚合与继承

    1.Maven聚合 我们在平时的开发中,项目往往会被划分为好几个模块,比如common公共模块.system系统模块.log日志模块.reports统计模块.monitor监控模块等等.这时我们肯定会 ...

  9. Maven POM元素继承

    为了减少重复代码的编写,我们需要创建POM的父子结构,然后在POM中申明一些配置供子POM继承,以实现"一处申明,多处使用的"目的.以之前的模块中的结构为基础,在account-a ...

随机推荐

  1. mozilla css developer center

    https://developer.mozilla.org/en-US/docs/Web/CSS

  2. Ant学习---第一节:Ant安装和简单使用

    一.下载 ant 插件,路径如下: http://ant.apache.org/bindownload.cgi 二.安装 ant 插件,解压下载下来的 ant 插件,配置环境变量(最好系统环境变量), ...

  3. WEB实时聊天 comet推技术

    转自:http://www.cnblogs.com/wodemeng/archive/2012/04/06/2435302.html 今天晚上朋友遇到web服务端推技术的问题,自己就查了下资料,学习了 ...

  4. Netsharp快速入门(之17) Netsharp基础功能(参照高级设置)

    5.2     参照高级设置 1. 以往来字段为例,打开平台工具-界面管理-列表管理,找到往来单位的资源节点,记下列表项目中的名称 2.记下往来单位部件工作区的id 3. 打开平台工具-界面管理-参照 ...

  5. 处理XML的几种方式

    晚上突然收到codeproject发来的订阅邮件,上面是关于用DOM出来XML,想总结一下有哪些方式可以轻松得处理XML DOM:这个再古老不过了,貌似大学开XML课程的时候,老师首推DOM XPat ...

  6. 【POJ】【2449】Remmarguts' Date

    K短路/A* 经(luo)典(ti) K短路题目= = K短路学习:http://www.cnblogs.com/Hilda/p/3226692.html 流程: 先把所有边逆向,做一遍dijkstr ...

  7. javascript中继承(一)-----原型链继承的个人理解

    [寒暄]好久没有更新博客了,说来话长,因为我下定决心要从一个后台程序员转为Front End,其间走过了一段漫长而艰辛的时光,今天跟大家分享下自己对javascript中原型链继承的理解. 总的说来, ...

  8. 重定向 vs output redirect

    http://asawicki.info/files/visual_cpp_redirect.png http://asawicki.info/news_1496_redirecting_output ...

  9. CNAME

    CNAME指别名记录也被称为规范名字.这种记录允许您将多个名字映射到同一台计算机. 通常用于同时提供WWW和MAIL服务的计算机.例如,有一台计算机名为“host.mydomain.com”(A记录) ...

  10. jquery的show/hide性能测试

    这篇文章是jQuery各种 show/hide方式的性能测试.作者之所以测试这个源于Robert Duffy在SanFrancisco举行的jQuery大会上的一句话:“.hide()和.show() ...