C++中多态相关知识
1.多态的概念
1.1概念
- 多态的概念:通俗来说,就是
多种形态
,具体点就是去完成某个行为
,当不同的对象去完成时会产生出不同的状态
- 举个例子:比如买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票
2.多态的定义及实现
2.1多态构成的条件
- 多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价
- 在继承中要构成多态还有两个条件:
Ⅰ
.派生类中,必须对基类的虚函数进行重写
,被调用的函数必须是虚函数Ⅱ
.必须通过基类的指针
或者引用
去调用虚函数
2.2虚函数
- 虚函数:即被virtual修饰的类成员函数称为虚函数
2.3虚函数的重写
- 虚函数的重写:派生类中有一个
跟基类完全相同的虚函数
(即派生类虚函数与基类虚函数的返回值类型
、函数名字
、参数列表完全相同
),称子类的虚函数
重写了基类的虚函数
- 这里有一个注意的点:在重写基类的虚函数时,派生类的虚函数不加
virtual
关键字,也可以构成重写
,因为基类的虚函数被继承下来依然保持着虚函数的属性
,但是这样的写法不太规范,并不建议使用
2.3.1虚函数重写的两个例外
Ⅰ
.协变:(基类与派生类虚函数返回值类型不同)- 派生类重写基类虚函数时,与基类虚函数返回值类型不同。即
基类虚函数返回基类对象的指针或者引用
,派生类虚函数返回派生类对象的指针或者引用
时,称为协变
Ⅱ
.析构函数的重写:(基类与派生类析构函数的名字不同)- 如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,即使基类与派生类析构函数名字不同。虽然函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称
统一处理成destructor
2.4 C++11 overrride 和 final
- 从上面可以看出,C++对函数重写的要求比较严格,但是有些情况下由于疏忽,可能会导致函数名字母次序写反而无法构成重载,而这种错误在编译期间是不会报出的,只有在程序运行时没有得到预期结果才来debug会得不偿失,因此:
C++11
提供了override
和final
两个关键字,可以帮助用户检测是否重写
- final:修饰虚函数,表示该虚函数不能再被继承
- override:检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错
2.5重载、覆盖(重写)、隐藏(重定义)的对比
3.抽象类
3.1概念
- 在虚函数的后面加上
=0
,则这个函数为纯虚函数
。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象
。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承