派生类:
定义语法:
class 派生类名 : 继承方式 基类名1, 继承方式 基类名2, …, 继承方式 基类名n
{
派生类成员声明;
};
一个派生类可以同时由多个基类,这种情况称为多继承。
一个派生类只有一个直接基类的情况,称为单继承。
派生类成员:
是指除了从基类继承来的所有成员之外,新增加的数据和函数成员。
派生类生成过程:
1、吸收基类成员 2、改造基类成员 3、添加新的成员
由于在派生过程中,基类的构造函数和析构函数是不能被继承的,因此要实现一些特别的初始化和扫尾清理工作,就要再派生类中加入新的构造函数和析构函数。
访问控制: 1、共有继承:
当类的继承方式为公有继承时,基类的公有和保护成员的访问属性在派生类中不变,而基类的私有成员不可直接访问。
2、私有继承:
当类的继承方式为私有继承时,基类中的公有成员和保护成员都以私有成员身份出现在派生类中,而基类的私有成员在派生类中不可直接访问。
可以把继承得到的私有方法重新创建一个公有方法进行覆盖重写:
void Move(float xOff, float yOff){Point::Move(xOff, yOff);}
3、保护继承:
保护继承中,基类的公有和保护成员都以保护成员的身份出现在派生类中,而基类的私有成员不可直接访问。
这样,派生类的其他成员就可以直接访问从基类继承类的公有和保护成员了。
类型兼容规则:
1、派生类的对象可以赋值给基类对象 2、派生类的对象可以初始化基类的引用 3、派生类对象的地址可以赋值给基类的指针
类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代
在替代之后,派生类对象就可以作为基类的对象使用,但只能使用从基类继承的成员。
派生类的构造函数:
如果基类声明了带有形参的构造函数时,派生类就应当声明构造函数:
派生类名 :: 派生类名(参数总表) : 基类名1(),…, 基类名n(), 内嵌对象名1(内嵌对象参数表1),…, 内嵌对象名m(内嵌对象参数表m) { 派生类新增成员的初始化语句; } //注:基类名和成员对象名的顺序是随意的
派生类构造函数执行的一般次序如下:
1、调用基类的构造函数 2、调用内嵌成员对象的构造函数 3、派生类的构造函数中的内容
复制构造函数:
如果要为派生类编写拷贝构造函数,则需要为基类相应的拷贝构造函数传递参数,例如,C类是B类的派生类,C类的拷贝构造函数形式如下:
C :: C(C &c1) : B(c1){…}
派生类的析构函数:
在派生过程中,基类的析构函数也不能继承下来,如果需要析构的话,就要在派生类中声明新的析构函数。派生类析构函数的声明方法与没有继承关系的累中析构函数的声明方法完全相同,只要在函数体中负责把派生类新增的非对象成员的清理工作做好就够了,系统会自己调用基类及对象成员的析构函数来对基类及对象成员进行清理。
派生类成员的作用域分析:
1、在没有虚函数的情况下,如果派生类中声明了与基类成员函数同名的新函数,即使函数的参数表不同,从基类继承的同名函数的所有重载形式也都会被隐藏。 2、在没有虚函数的情况下,如果某派生类的多个基类拥有同名的成员,同时,派生类又新增这样的同名成员,在这种情况下,派生成员将隐藏所有基类的同名成员。
虚基类
解决的问题:当某类的部分或全部直接基类是从另一个共同基类派生而来时,在这些直接基类中从上一级共同基类继承来的成员就拥有相同的名称。这些同名数据成员在内存中同时拥有多个拷贝,同一个函数名会由多个映射,为了只保留一个拷贝,所以引入了虚基类:
class 派生类名 : virtual 继承方式 基类名