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

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. cocos2dx 2.0+ 版本,IOS6.0+设置横屏

    使用cocos2dx 自带的xcode模板,是不能正常的设置为横屏的. 一共修改了三个地方: 在项目属性中:Deployment Info中,勾选上 Landscape left,以及 Landsca ...

  2. C# 非独占延时函数 非Sleep

    在C#窗口程序中,如果在主线程里调用Sleep,在Sleep完成之前, 界面呈现出假死状态,不能响应任何操作! 下边实现的是非独占性延时函数,延时过时中界面仍可响应消息: public static ...

  3. VBS基础篇 - 常用函数

    Option Explicit '*********************************Date/Time函数******************************* 'CDate函 ...

  4. Android -- 获取摄像头帧数据解码

    由于Android下摄像头预览数据只能  ImageFormat.NV21 格式的,所以解码时要经过一翻周折. Camera mCamera = Camera.open(); Camera.Param ...

  5. 向Array中添加冒泡排序

    冒泡排序思想 通过在无序区的相邻元素的比较和替换,使较小的元素浮到最上面. 冒泡排序实现 Function.prototype.method = function(name, func){ this. ...

  6. Microsoft SQL Server 存储过程举例

    -- if SP is existed, drop it. if (object_id('InvHoldToDPS', 'P') is not null) drop proc InvHoldToDPS ...

  7. window8左下角窗口和右上角窗口失效解决方法

    win8系统有时会出现任务栏和桌面点击没反应 小常识: “Windows徽标键” 这个键,左右各一个,称为“Windows徽标键”,键冒上的图案为Windows徽标,由此得名. [知识链接]位于计算机 ...

  8. Posix线程编程指南(2) 线程私有数据

    概念及作用 在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据.在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有.但有时应用程序设计中有必要提供 ...

  9. 单点登陆CAS安装过程中可能遇到的问题

    可能遇到的问题: 错误: java.security.cert.CertificateException: No name matching localhost found 原因: keystore里 ...

  10. Brush Mode --- Nyoj 236 分类: Brush Mode 2014-04-02 06:56 116人阅读 评论(0) 收藏

    心急的C小加 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的时间 ...