如何免费制作企业网站,新郑网络推广,广州seo服务公司,杭州 app开发公司一、继承与友元
友元关系不能够继承#xff08;就像父亲的朋友不一定是自己的朋友#xff09;
具体实现起来就是父类的友元可以访问父类的成员#xff0c;但是不可以访问子类的成员
二、继承与静态成员
子类的静态成员变量本质上与父类的是同一份#xff0c;存储在静态…一、继承与友元
友元关系不能够继承就像父亲的朋友不一定是自己的朋友
具体实现起来就是父类的友元可以访问父类的成员但是不可以访问子类的成员
二、继承与静态成员
子类的静态成员变量本质上与父类的是同一份存储在静态区中所以可以继承
例如
class Person
{
public:static int _count 0
}
可以直接继承到子类
三、单继承与多继承
3.1单继承是什么
一个子类只有一个直接父类如
class Student : public Person
{}
3.2多继承
3.2.1定义
一个子类有两个及以上的直接父类如
class Assistant : public Student,public Teacher
{}
3.2.2菱形继承中的数据冗余和二义性
用例子来说明 如图Student与Teacher都继承自Person而Assistant又多继承了Student与Teacher那么这时候Student与Teacher中属于Person的那一部分就会出现冗余我们称之为数据冗余。
当我们运行下面一段代码的时候
Assistant a;
a._name;
此时我们会发现在Assistant中有两份_name一份属于Student一份属于Teacher,因此运行时会因为不知访问那个而报错我们称之为二义性。
3.2.3virtual虚继承
按照之前分析我们已经知道了数据冗余和二义性的存在那么应该如何解决它呢
为此我们引入了virtual关键字来完成虚继承的概念虚继承后我们可以得到如下图的存储方式 使用虚继承的方法也很简单,只需要在继承共有父类的时候加上virtual关键字
class Student: virtual public Person
{}
3.2.3补复杂菱形继承时的位置
假如要完成如下图的复杂菱形继承 分析可知在继承A的时候会出现数据冗余和二义性的问题因此我们要在
A-B
A-C
这两个继承的时候使用virtual来修饰
3.3总结
在实际应用当中我么并不推荐使用菱形继承因为这会降低代码可读性虽然iostream就是菱形继承但是使用多继承是完全没问题的
四、继承和组合
4.1两者的本质都是复用
4.1补黑盒测试和白盒测试的概念
白盒测试可见底层代码的实现是对代码功能的实现过程进行测试对技术要求高
黑盒测试不可见代码的底层实现直接对代码的功能进行测试对技术要求低
4.2is-a关系与has-a关系特指类之间的关系
public继承是一种is-a关系就是说每个派生类对象都是一个基类对象
组合是一种has-a关系假设B组合了A每个B对象中都有一个A对象例如我们在vector类模板中在成员变量列表使用了迭代器类来作为成员变量
4.2补在程序设计中我们推荐“高内聚低耦合”的代码形式
其中低耦合特指两个类之间关系我们希望类与类之间关系不要太紧密。
4.3组合的好处
组合的原则是在类中少放公用大多在保护中实现仅仅向外展示功能接口因此组合十分符合低耦合的形式
4.4继承与组合的对比
①继承允许根据基类的实现来定义派生类的实现这种以生成派生类为目的的复用我们称为白箱复用但是因为白箱可视度高所以基类的改变对派生类影响很大耦合度比较高
②对象组合是继承之外的另一种复用方式class Person中定义保护成员hand h1
而hand是另外实现的一个类这时两个类之间体现出了对象组合
在这个例子中我们称hand类被Person类组合了被组合的对象通常需要有良好的接口这种复用风格成为黑箱复用因为对象内部不可见耦合度低
4.5is-a与has-a关系的应用场景
has-a关系时用对象组合例如人体和手
is-a关系时用继承例如植物和水果
当has-a与is-a都符合的时候用组合如list与queue