-
-
[分享]C++基础十四-抽象类
-
2021-9-30 14:20 7885
-
纯虚函数
在C++ 中,可以将虚函数声明为纯虚函数,在虚函数声明的结尾加上 =0 ,表明此函数为纯虚函数,语法格式为:
1 | virtual 返回值类型 函数名 (函数参数) = 0 ; |
最后的 =0 并不表示函数返回值为0,它只起形式上的作用,告诉编译器这是一个纯虚函数。纯虚函数没有函数体,只有函数声明。
抽象类
包含纯虚函数的类称为抽象类(Abstract Class),抽象类通常作为基类,让派生类去实现纯虚函数,同时派生类必须实现纯虚函数才能被实例化,否则还是一个抽象类。
Aircraft.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #pragma once #include <iostream> using namespace std; class CAircraft { public: CAircraft(); ~CAircraft(); virtual void Refuel(); / / 加燃油,虚函数 virtual void FlyMode() = 0 ; / / 飞行方式,纯虚函数 }; class CHelicopter :public CAircraft { public: CHelicopter(); ~CHelicopter(); void FlyMode(); }; class CFighter :public CAircraft { public: CFighter(); ~CFighter(); void Refuel(); void FlyMode(); }; |
Aircraft.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include "Aircraft.h" CAircraft::CAircraft() { } CAircraft::~CAircraft() { } void CAircraft::Refuel() { cout << "通用燃油" << endl; } void FlyMode() { cout << "停止起飞" << endl; } CHelicopter::CHelicopter() { } CHelicopter::~CHelicopter() { } void CHelicopter::FlyMode() { cout << "山地打击" << endl; } CFighter::CFighter() { } CFighter::~CFighter() { } void CFighter::Refuel() { cout << "航空煤油" << endl; } void CFighter::FlyMode() { cout << "高空巡航" << endl; } |
Test.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include <iostream> #include "Aircraft.h" class CPilot { public: CPilot(); ~CPilot(); void RefuelPlane(CAircraft * pAircraft); void DrivePlane(CAircraft * pAircraft); }; CPilot::CPilot() { } CPilot::~CPilot() { } void CPilot::RefuelPlane(CAircraft * pAircraft) { pAircraft - >Refuel(); } void CPilot::DrivePlane(CAircraft * pAircraft) { pAircraft - >FlyMode(); } int main() { CPilot pilot; CAircraft * Z20 = new CHelicopter; CAircraft * J20 = new CFighter; pilot.RefuelPlane(Z20); pilot.DrivePlane(Z20); pilot.RefuelPlane(J20); pilot.DrivePlane(J20); return 0 ; } |
上述代码体现了最经典的多态场景,给飞行员不同的飞机,就能表现出不同的结果。虚函数和纯虚函数都能做到这一点,区别是,子类如果不提供虚函数的实现,就会自动调用基类的缺省方案,而子类如果不提供纯虚函数的实现,则编译将会失败。基类提供的纯虚函数实现版本,无法通过指向子类对象的基类类型指针或引用来调用,因此不能作为子类相应虚函数的备选方案。
抽象类的用法
使用虚函数
当基类的某个成员方法,在大多数情形下都应该由子类提供个性化实现,但基类也可以提供一个备选方案的时候,应该将其设计为虚函数。例如航空器的加油行为,每种不同的航空器原则上都应该有自己的个性化燃油加充方式,但也可以有一种通用的燃油加充方式。
使用纯虚函数
当基类的某个成员方法,必须由子类提供个性化实现的时候,应该将其设计为纯虚函数。例如航空器的飞行动作,逻辑上每种航空器都必须提供为其设计的个性化飞行方式,并没有一种通用的飞行方式。
纯虚函数的实现
基类提供的纯虚函数的实现版本,并非为了多态性考虑,因为指向子类对象的基类指针和引用无法调用该版本。纯虚函数在基类中的实现跟多态性无关,它只是提供了一种语法上的便利,在变化多端的应用场景中留有后路。
使用多态
使用一个基类类型的指针或者引用,来指向子类对象,进而调用经由子类复写的个性化的虚函数,这是C++实现多态性的一个最经典的场景。
虚函数和纯虚函数的区别
1、在类成员方法的声明语句前加上关键字virtual,成为虚函数。
2、在虚函数的声明语句末加上 =0 ,成为纯虚函数。
3、子类可以重新定义基类的虚函数,这个行为称为复写(override)。
4、不管是虚函数还是纯虚函数,基类都可以为他们提供实现(implementation)。
5、子类可自主选择是否要提供一份属于自己的个性化虚函数实现。
6、子类必须提供一份属于自己的个性化纯虚函数实现。
抽象类的特点
- 抽象类不允许创建对象。
- 抽象类元素不能作为函数的返回值,不能作为函数的参数。
- 抽象类的指针和引用可以做函数参数,可以做返回值,可以指向子类对象。
github:https://github.com/0I00II000I00I0I0
bilibili:https://space.bilibili.com/284022506
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课