首页
社区
课程
招聘
[分享]C++基础十四-抽象类
2021-9-30 14:20 7885

[分享]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直播授课

最后于 2021-9-30 14:21 被流照君编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回