一、基本概念:继承、基类、派生类
继承:在定义一个新的类B时,如果该类与某个已有的类A相似 (指的是B拥有A的全部特点),那么就可以把A作为一个基类,而把B作为基类的一个派生类 (也称子类)。
派生类:通过对基类进行修改和扩充得到的类。
(1)扩充: 在派生类中,可以添加新的成员变量和成员函数
(2)修改: 在派生类中,可以重新编写从基类继承得到的成员
(3)覆盖:在派生类中,可以定义一个和基类成员同名的成员,这叫覆盖。在派生类中访问这类成员时,缺省的情况是访问派生类中定义的成员。要在派生类中访问由基类定义的同名成员时,要使用作用域符号::。
派生类一经定义后,可以独立使用,不依赖于基类。
派生类定义方式:class 派生类名:派生方式说明符 基类名{...}
派生方式说明符有三种,分别是public,private,protected
派生类对象的大小,等于基类对象的大小加上派生类对象自己的成员变量的大小。在派生类对象中,包含着基类对象和本身新增的对象,而且基类对象的存储位置位于派生类对象新增的成员变量之前。
二、派生类的成员组,可见性
①公有继承 (public)
公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。
1.基类成员对其对象的可见性:
公有成员可见,其他不可见。这里保护成员同于私有成员。
2.基类成员对派生类的可见性:
公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员。
3.基类成员对派生类对象的可见性:
公有成员可见,其他成员不可见。
②私有继承 (private)
私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。
1.基类成员对其对象的可见性:
公有成员可见,其他成员不可见。
2.基类成员对派生类的可见性:
公有成员和保护成员是可见的,而私有成员是不可见的。
3.基类成员对派生类对象的可见性:
所有成员都是不可见的。
③保护继承 (protected)
1.基类成员对其对象的可见性:
公有成员可见,其他不可见。这里保护成员同于私有成员。
2.基类成员对派生类的可见性:
公有成员和保护成员是可见的,而私有成员是不可见的。
3.基类成员对派生类对象的可见性:
所有成员都是不可见的。
与私有继承方式的情况相同。两者的区别仅在于对派生类的派生类成员而言,对基类成员有不同的可见性。
保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。
=>
另一种存取权限说明符:protected
基类的private成员:可以被下列函数访问
1.基类的成员函数
2.基类的友元函数
基类的public成员:可以被下列函数访问
1.基类的成员函数
2.基类的友元函数
3.派生类的成员函数
4.派生类的友元函数
5.其他的函数
基类的protected成员:可以被下列函数访问
1.基类的成员函数
2.基类的友元函数
3.派生类的成员函数
4.派生类的友元函数
三、派生类的构造,析构
①派生类的构造函数
我们创建一个武器weapon类,sword类作为weapon的派生类,继承类型为public
我们在创建一个sword类时,会自动生成一个与之对应的weapon类,那么这时在书写sword构造函数时,就应当考虑weapon如何初始化,即要考虑weapon的构造函数。
可见这样的写法行不通的,因为public继承无法访问基类的private成员,我们应该通过调用weapon的成员函数才能访问weapon的private成员变量,然后对其进行初始化,即调用weapon自己的构造函数。
注意:在执行一个派生类的构造函数之前,总是先执行基类的构造函数。
②派生类的析构函数
我们在析构一个派生类时,同理应当考虑基类的析构,方式与处理构造函数时类似。
注意:派生类的析构函数被执行时,执行完派生类的析构函数后,自动调用基类的析构函数。即先调用派生类析构函数,再调用基类析构函数。
四、派生类与基类的指针类型转换
(1)Public 继承的赋值兼容规则:
1.派生类的对象可以赋值给基类对象
2.派生类对象可以初始化基类引用
3.派生类对象的地址可以赋给基类指针
(反之均不成立)
(2)基类与派生类的指针强制转化:
(要求:public继承)
我们可以把base_ptr视作一个Base类的对象,可以通过它直接访问Base类的成员(尽管他实际指向的是一个派生类对象),但是我们无法通过它直接访问派生出来的Derived类中的成员,即不能通过它访问属于Derived类但并不属于Base类的成员。
我们可以通过强制类型转换把base_ptr重新转换成Derived类的指针
五、直接基类和间接基类
如果A派生B,B派生C,C派生D....
那么我们称
A为B的直接基类,为C、D的间接基类
B为C的直接基类,为D的间接基类
C为D的直接基类
在声明派生类时,只需要列出其直接基类,然后派生类会自动向上继承其间接基类。
派生类的成员包括了其自身的成员、直接基类的成员、间接基类的成员。