新闻中心

EEPW首页>嵌入式系统>设计应用> 类的封装与继承

类的封装与继承

作者: 时间:2009-12-14 来源:网络 收藏

上述例程中,对于C而言,有两个父类B1、B2,有1个祖父类A,从而A、B1、B2、C构成了典型的菱形结构。使用了虚基类的菱形结构里,对象的内存布局中只有1个A,即祖父类的部分只有1份,且放在最后面,排放顺序是B1+B2+C+A。如果没有用虚机制,那么在C对象的内存布局中会出现2份A部分,这也就是所谓的V型。相应的对象布局为A+B1+A+B2+C。在V型中不能直接从C(即孙子类)直接转型到A(即祖父类)因为在对象的布局中有2份祖父类的实体,分别从B1、B2而来。编译器在决议时会存在二义性,它不知道转型后到底用哪一份实体。可以通过先转型到某一父类,然后再转型到祖父类来解决。但使用这种方法时,如果改写了祖父类的成员变量的内容,runtime不会同步2个祖父类实体的状态,因此可能会有语义错误。
多继承结构允许1个对象继承来自不同对象的特征,但也会带来新的问题。我们看下面的规则。规则10-2-1(推荐): 多继承层级中,可访问的实体名称应当是相互独立、不同的。如果名称含混不清,编译器将报告名称冲突,同时不会武断生成不符合预期的代码。但是这种含混不清对于开发者来说,并不容易察觉。当成员函数是虚函数时,还有一个需要特别注意的地方:通过explicitly引用基类来解决名称含混的问题,将会去除函数的“虚”特性。对于本条规则也有例外的情况,比如:相关的重载函数应当看作具有相同的入口。相关说明程序如下:


上述程序定义D时,无法分辨成员中的count和foo()到底来自B1还是B2,造成了不必要的困扰。代码重用的目的是按不同方式重复使用代码来实现类、结构、函数等,这就要求代码必须是通用的,且通用代码不受使用数据类型和操作的影响,即无论使用什么数据类型通用代码都是不变的。于是C++提出了类模板的概念:类模版可以为类声明1种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能取任意类型。MISRA C++:2008就模板的使用也给出了详细的规则。
规则14-5-2(强制): 当具有单参数的模版构造函数时,必须声明拷贝构造函数。
与开发人员预期的不同,模版的构造函数不会禁止编译器生成拷贝构造函数。这样当成员函数要求进行深拷 贝的时候,可能会导致不正确的拷贝语句被执行。这样的问题往往在程序设计初期不会引起重视,等到面对莫名其妙的问题时,再回过头来寻找原因,只能一筹莫展。如果在程序设计时就遵循MISRA C++:2008中相关的规则,自然可以避免这样的困扰。


4 小 结
本文是学习MISRA C++系列连载讲座之三。从“统筹兼顾”的角度和大家一起学习讨论了MISRA C++:2008中关于类、派生类、成员访问的控制、特殊的成员函数以及模版的相关规则。其中有意思的例子还有很多,限于篇幅,就不一一展开叙述了。请继续关注本系列讲座的第4讲:异常机制的使用。


上一页 1 2 3 下一页

关键词:继承C语言

评论


相关推荐

技术专区

关闭