基类与派生类的转换
公有派生类对象可以当作基类对象使用,反之则不行;
派生类对象可以隐含的转换为基类对象
派生类对象可以初始化为基类的引用
派生类的指针可以隐含转换为基类的指针
派生类构造函数
如果派生类不新增数据成员,可以通过继承派生类构造函数;使用语句using B::B;B为类名
如果不继承基类构造函数,则:
派生类新增数据成员,由派生类构造函数初始化
继承来的成员:自动调用积累构造函数初始化
派生类的构造函数需要给基类构造函数传递参数
多继承派生类的构造函数初始化顺序
首先在初始化列表调用基类构造函数:调用顺序按继承时声明的顺序(不是按照书写的先后次序)
其次初始化派生类中的成员:按照派生类成员定义顺序进行初始化
派生类的复制构造函数
- 复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数。
- 基类的复制构造函数形参类型是基类对象的引用,实参可以是派生类对象的引用
- 例如: C::C(const C &c1): B(c1) {…}
派生类的析构函数中不需要显式的调用基类的析构函数,基类的析构函数将在派生类析构函数执行完后执行
作用域限定
当派生类与基类中有相同成员时:
- 若未特别限定,则通过派生类对象使用的是派生类中的同名成员。
- 如要通过派生类对象访问基类中被隐藏的同名成员,应使用基类名和作用域操作符(::)来限定。
二义性问题
- 如果从不同基类继承了同名成员,但是在派生类中没有定义同名成员,“派生类对象名或引用名.成员名”、“派生类指针->成员名”访问成员存在二义性问题
- 解决方式:用类名限定
虚基类
- 需要解决的问题
- 当派生类从多个基类派生,而这些基类又共同基类,则在访问此共同基类中的成员时,将产生冗余,并有可能因冗余带来不一致性
- 虚基类声明
- 以virtual说明基类继承方式
- 例:class B1:virtual public B
- 作用
- 主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题
- 为最远的派生类提供唯一的基类成员,而不重复产生多次复制
- 注意:
- 在第一级继承时就要将共同基类设计为虚基类。
虚基类及其派生类构造函数
- 建立对象时所指定的类称为最远派生类。
- 虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。
- 在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中为虚基类的构造函数列出参数。如果未列出,则表示调用该虚基类的默认构造函数。
- 在建立对象时,只有最远派生类的构造函数调用虚基类的构造函数,其他类对虚基类构造函数的调用被忽略。
多态:方法的行为取决于调用该方法的对象,这种复杂行为称为多态。
对于使用virtual关键字的方法的基类方法重定义说明:是用对象调用该方法时,根据对象选择具体调用(是基类中的,还是在派生类中重定义的)对象时基类对象则调用基类方法,对象时派生类对象则调用配生类方法,当使用引用或指针调用该方法,则根据引用或指针指向对象的类型选择具体调用那种方法。
总之一句话:如果在派生类中重定义基类中的方法,将基类方法声明为虚的,这样程序将根据对象类型而不是引用或指针类型选择方法的版本。
基类指针可以指向派生类对象,派生类指针不可以指向基类对象
举个例子
有个people类是基类,成员有姓名和身份证号,有个派生类学生student,添加了成员学号,现在如果你说的这个情况成立student的指针----pt让他指向people成员t,则t只有两个成员变量,而*pt有3个,现在pt->学号这个变量在pt下是可以使用的,但它指向的实体却没有这个变量,所以出错,于是C++直接就避免了这样的隐式转换
【1】