【整理归纳】继承与多态(继承)
2017-04-13 本文已影响101人
pangdaaa
继承
为什么要继承
不做重复的事情,减少不必要的工作,提高工作效率。
继承方式
继承方式 | 基类的public成员 | 基类的protected成员 | 基类的private成员 | 访问控制关系 |
---|---|---|---|---|
public继承 | public | protected | 不可见 | 基类的非私有在子类的访问属性不变 |
protected继承 | protected | protected | 不可见 | 基类的非私有成员都成为子类的保护 |
private继承 | private | private | 不可见 | 基类的非私有成员都成为子类得私有 |
重载、隐藏(重定义)与覆盖(重写)
- 重载:是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。
- 隐藏(重定义):是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。
- 覆盖(重写):是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同,派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。
多继承与多重继承
- 多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承;
-
多重继承(菱形继承):多个类继承了同一个公共基类,而这些派生类又同时被一个类继承。
如图:
多重继承
虚拟继承
先看一段代码
class Person
{
public :
string _name ; // 姓名
};
class Student : public Person
{
protected :
int _num ; //学号
};
class Teacher : public Person
{
protected :
int _id ; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected :
string _majorCourse ; // 主修课程
};
void Test ()
{
// 显示指定访问哪个父类的成员
Assistant a ;
a.Student ::_name = "xxx";
a.Teacher ::_name = "yyy";
}
对上方菱形继承的代码进行分析后,它的对象模型如图:
菱形继承对象模型.png虚拟继承就是解决菱形继承的二义性和数据冗余的问题
- 虚继承解决了在菱形继承体系里面子类对象包含多份父类对象的数据冗余和浪费空间的问题。
- 虚继承体系看起来好复杂,在实际应用我们通常不会定义如此复杂的继承体系。一般不到万不得已都不要定义菱形结构的虚继承体系结构,因为使用虚继承解决数据冗余问题也带来了性能上的损耗。