c++继承总结
来源:互联网 发布:2017色情交友软件 编辑:程序博客网 时间:2024/05/21 14:04
is-a
public继承,是一种D是B的一种,但B不一定都是D。
在这种继承关系下,通常意义上的理解,会在程序中出现乱流。例如,企鹅是一种鸟,又鸟派生出的企鹅,却不能飞。
因此,在鸟中派生出会飞的鸟,再派生出企鹅会更好。即,采用双继承区分。
即使如此,此刻我们仍然未能完全处理好这些鸟事,因为对某些软件系统而言,可能不需要区分会飞的鸟和不会飞的鸟。如果你的程序忙着处理鸟啄和鸟翅,完全不在乎飞行,原先的"双classes 继承体系"或许就相当令人满足了。这反映出一个事实,世界上并不存在一个"适用于所有软件"的完美设计。所谓最佳设计,取决于系统希望做什么事,包括现在与未来。如果你的程序对飞行一无所知,而且也不打算未来对飞行"有所知",那么不去区分会飞的鸟和不会飞的鸟,不失为一个完美而有效的设计。实际上它可能比"对两者做出区隔"更受欢迎,因为这样的区隔在你企图塑模的世界中并不存在。
还有一种思想,就是让企鹅继承鸟,但是,在企鹅的飞行函数中,提出错误,不能飞!这是运行期错误。
或者,不定义飞行函数,那么对于企鹅飞行的调用,在编译期,就会报错。
两者不同,但是,好的接口,防止无效的代码通过编译。所以。。。
复合:某种类型中含有其他类型。has-a)或is-implemented-in也rms-of 根据某物实现出
这两种关系分别用于不同的领域
当复合发生在程序中的对象属于的应用领域。此时,就是has-a关系。
当复合发生在缓冲区,互斥器,查找树等相当于软件的实现域时,就是根据某物实现。
要注意区分is-a与根据某物实现的区别。
Private 继承意味implemented-in-terms-of根据某物实现出
pnvate 继承意味只有实现部分被继承,接口部分应略去。
它跟复合,一样,该如何取舍呢,
尽量用复合,必要是采用私有继承。何时才是必要?主要是当protected 成员和虚 函数牵扯进来的时候。其实还有一种激进情况,那是当空间方面的利害关系足以踢翻private 继承的支柱时。
采用私有继承,可以免除程序在继承后,继承到的基类函数,变成接口的混乱感觉。
也可以用复合代替私有继承,我们在类中声明一个私有的嵌套类。该类以共有形式继承需要继承的类。然后,在原类中,申明一个嵌套类私有对象。
两种方式:
第一种,当原类有派生类时,无法阻止重新定义虚函数。但第二种方法却可以。因为,原类的派生类。无法取得私有的嵌套对象。因为,无法继承,或者重新定义虚函数,类似于Jave中的(final)。c#中的sealed。
同时,第二种方法,更加优化了编译依存性。
private 继承主要用于当一个意欲成为derived class 者想访问一个意欲成为base class 者的protected 成分,或为了重新定义一或多个virtual 函数
但这时候两个classes 之间的概念关系其实是is-implemented-in-terms-of (根据某物实现出)而非is-a。然而我也说过,有一种激进情况涉及空间最优化,可能会促使
你选择"private 继承"而不是"继承加复合"。
关于派生方式下的隐藏规则:
公有继承下:
根据C++名称遮掩规则,派生类和基类有相同名字的函数,成员变量,都会发生隐藏。不管函数是否为虚函数,不管参数是否相同,派生的同名函数,都会隐藏基类的同名函数。解决方式:用using base:fun;让基类同名函数,在派生类可见。
私有继承下:
由于继承方式为私有。因为,using 方式会让继承而来的某给定名称的所有同名函数,在派生类,都可见。于是,此时,采用inline的转交函数。即,在派生类同名函数中,采用base:fun();方式、
区分接口继承和实现继承
对于类的继承,通常有两部分组成,一部分是接口,一部分是实现。
纯虚函数的目的,是为了让派生类只继承函数接口。但是,可以给纯虚函数一个定义代码,在调用的时候,指定类名称。
即:纯虚函数的申明是对派生类说。你必须提供该函数,但我不干涉你怎么实现。
虚函数目的是为了让派生类继承类的接口和缺省实现。
即:基类对派生类说。你必须提供该函数,但如果你不想自己实现,可以用我的默认实现、
但这有可能造成危险,在新添加一个类的时候,没有要求说明要缺省实现该函数而直接继承缺省行为。因此,造成灾难。
可行之法是。我们讲虚函数,改为纯虚函数,同时,添加一个普通函数实现缺省行为,让派生类在虚函数中,inline调用该缺省普通函数。注意,该默认普通函数,应该设计为protected
有些人反对用以不同的函数,分别提供接口和缺省实现。于是,采用纯虚函数在派生类中重新声明的方式,同时让它们拥有自己的实现。此时,纯虚函数在基类有自己的定义,也是public的。派生类在各自类中,重写自己的实现。也可以是用基类的缺省行为。
普通函数:
目的是为了令派生类继承接口以及一份强制实现、
千万记住:绝对不要重新定义继承而来的非虚函数。因为这会和public继承的is-a关系,以及类中的不变性,凌驾其特异性发生矛盾。
同时,千万不要重新定义继承而来的虚函数的缺省参数值。因为缺省参数值是静态绑定的,而虚函数,是动态绑定的。
假设调用一个派生类的虚函数的同时,又在使用基类为它设定的缺省参数值,导致该函数调用有个奇怪的组合,基类和派生类的申明各占一半。
C++之所以有虚函数的缺省值,是为了效率,在运行期,决定虚函数的缺省参数,提前到编译期。
关于空类问题
所谓空类,就是说,不带任何数据,这样的类没有非静态成员变量,没有虚函数,也没有虚基类,因此,这样的空类对象,不使用任何空间,因为没有任何隶属对象的数据需要存储,然而,由于技术上的理由,C++裁定独立(非附属)对象必须有非零大小,在大多数编译器中,这样的空类大小为1.因为,面对这样的对象,C++官方,通常安插一个char,同时,由于字节对齐问题,可能大于1.需要注意的是,这里,必须是独立,非附属对象。也就是说,这个约束,不适合于派生类对象的基类成分 。例如EBO(空白基类优化)。即,你的类,私有继承一个空类。此时,大小为真正的类大小。但是,EBO只适合于单一继承。
- 【C++】继承总结
- C++——【继承】总结
- c++-关于菱形继承&虚继承的问题总结
- 继承总结
- 继承总结
- 继承总结
- 继承总结
- 继承总结
- 继承总结
- 继承总结
- 黑马程序员_ Objective C 封装,继承,多态总结
- C++___的虚拟继承的一些总结
- 【C++】第13章 类继承 知识点总结
- c继承
- C++----------------继承
- 【c#】继承
- C++:继承
- C++::继承
- 解决win7无关机、重启选项
- 程序员开发大型应用程序的技巧
- 【转载】CrystalReport for vs2010 水晶报表的发布问题以及捆绑发布 .
- 文件流操作
- 10经典语录
- c++继承总结
- VB.NET多线程应用
- 文件操作
- 一些重要知识点-转自eoeAndroid开发网
- HTML5 File Reader file upload 文件上传 test
- bss segment
- NET多线程同步方法:互斥锁(Lock)
- GOOGLE AdSense账号验证
- position:relative/absolute/IE6/z-index失效