sstream类使用,就是将字符串转换成string对象
1.概念
继承就是一个新类拥有全部被继承类的成员变量和成员函数
- 新产生的继承类有独有的成员变量和成员函数
- C++中把产生新类的被继承类叫做基类(父类);
由基类通过继承方式产生的新类叫做派生类(子类);
作用:继承是代码复用的重要手段;
实现方式:将相同的成员抽取出来,相同的部分单独实现一个类
2.继承权限
不同继承方式下,子类对父类中不同权限成员的访问限制
public继承:
- 父类的公有和保护成员->成为子类的公有和保护成员;
- 即子类拥有父类中的 公有和保护成员
private继承
- 父类的公有和保护成员->成为子类的私有成员;
即父类中的公有和保护成员,对子类的子类 和 外部程序私有;- 子类不能访问,外部也不能访问
protected继承
- 父类的公有和保护成员->成为子类的保护成员;
- 即父类中的公有和保护成员可作为子类的保护成员,在类继承层次中不间断被继承使用;
- 子类可以访问,外部不能访问
私有继承,虽然子类不能访问成员,但是私有成员已被子类继承,判断子类的大小,即可验证
class定义的类,默认是私有继承;
struct定义的类,默认是公有继承;
保护成员,子类可以访问父类保护成员,类外不能访问保护成员
父类不同的成员通过不同的继承权限,其在 子类 和 类外 的访问权限不同
3.父类和子类对象赋值转换(赋值兼容规则)
前提:必须是公有的继承方式才有赋值兼容规则(将子类对象看成一个父类对象)
- 可以将子类对象直接给父类对象赋值,反之不行
子类中的成员就被丢弃了
父类对象给子类对象赋值就不安全了- 可以让父类指针或引用指向子类对象,反之不行
子类指针想指向父类对象,子类指针必须强转
但是指针不能指向子类独有的成员
为什么
- 如果是public继承方式,子类和父类是is-a的关系,
is-a表示是一个- 即子类对象(看成)是父类对象
在类外 所有使用父类对象的位置都可以使用子类对象代替(这种叫向上转型)- 父子类的关系:狗是一个动物,动物不一定就是狗
4.继承中的作用域
继承体系中,父类和子类属于不同的作用域
所以子类访问父类的私有成员变量,就相当于子类在类外访问,就违反私有权限特性
同名隐藏(重定义)
子类和父类中有同名成员,优先访问子类中的同名成员,这种情况叫隐藏(或重定义)
对于成员变量,父子类中不管变量类型是否相同,都优先访问子类成员变量
对于成员函数,父子类中不管函数参数还是返回值是否相同,都优先访问子类成员函数
成员隐藏后使用
子类对象.父类::父类成员
方式访问父类成员
实际应用时,继承体系中最好不要定义同名的成员。
因为父子类是两个不同的作用域,所以函数同名不属于重载
5.构造子类对象
1.父类是默认构造
- 子类构造可以不定义
- 如果子类不定义构造,编译器会给子类生成一个默认构造
在生成的初始化列表处会显式调用父类构造函数,初始化继承的成员- 如果子类定义了构造,在初始化列表的位置,父类和子类成员都要初始化
2.父类是非默认构造
- 子类构造必须定义,且要在初始化列表处要显式调用父类构造
构造,拷贝,运算符重载,析构的继承实现
父子类构造函数调用顺序
先调用子类构造函数,在调用过程中调用子类构造的初始化列表处跳转到父类的构造函数
36行可以传子类对象s
子类是默认构造,不用在初始化列表处显示调用父类构造
拷贝构造是构造函数的一种重载,肯定是带默认值的,同父类构造
子类赋值运算符函数实现了,必须显示调用父类赋值函数
先调子类析构方法,编译器在子类析构函数最后调用父类析构
析构函数在子类定义了,不用显示调用父类析构
在调用拷贝构造,运算符重载时,都是先对父类成员变量先初始化赋值;
- 在初始化子类对象时,不能说先调用父类构造函数,再调用子类构造函数;
- 创建哪个类对象时就调用哪个类的构造;
要初始化所有变量,对于继承的变量,就需要调用父类的构造函数初始化紧接着执行父类构造的函数体,然后才执行子类的函数体- 析构哪个类对象时就调用哪个类的析构