CPP学习之——纯虚函数与抽象类(16.5)

一 概述

  • 一个虚函数通过初始化为0就变成了纯虚函数。
  • 这个纯虚函数是彻底无任何功能的,你不能直接来调用它,因为它是抽象的,它只有被子类继承并赋予新功能后才能被使用

二 概念分析

  • 一个类可以有多个纯虚函数,包含有纯虚函数的类叫做抽象类
  • 由于任何一个从抽象类派生的新类都会继承纯虚函数的特征——无任何功能,因此要创建这个新类的对象必须为每一个纯虚函数赋予功能,换一句话说,假如要将从人类派生出去的一个人说明为一个具体的人的话,那么必须为这个人赋予他的一些特征或者功能。假如不这么做的话,那么他也将是一个抽象的人,或者说是一个抽象的对象
  • 打个比方,你在书中看到的电视机是抽象的,它仅仅是一个词汇,你不能用它来看电视,但是电视机生产出来的电视机就不同了,它具备播放电视节目的功能,你可以用它来播放电视节目,看VCD,甚至玩电视游戏
  • 本例中,Human类仅仅起到了为派生类提供一个接口的作用,这个接口类的纯虚函数可以没有任何作用,派生类将这些纯虚函数继承过来,然后给与它不同的功能
  • 而多态性又保证了用户在输入不同的数字时调用不同的虚函数

三 示例演示及结果输出

3.1 代码

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include<iostream>
using namespace std;
class human
{

public:
virtual void smart()=0;
virtual void beautiful()=0;
virtual ~human(){cout<<"析构human"<<endl;}
human(){cout<<"构造huamn"<<endl;}
};
class father:virtual public human{

public:
virtual void smart(){cout<<"父亲很聪明"<<endl;}
virtual void beautiful(){cout<<"父亲不是很帅"<<endl;}
father(){cout<<"构造father"<<endl;}
virtual ~father(){cout<<"析构father"<<endl;}
};
class mother:virtual public human
{
public:
virtual void beautiful(){cout<<"母亲很漂亮。。"<<endl;}
mother(){cout<<"构造mother"<<endl;}
virtual ~mother(){cout<<"析构mother"<<endl;}
virtual void smart(){cout<<"母亲并不聪明"<<endl;}
};
class son:public father,public mother
{
public:
son(){cout<<"构造son"<<endl;}
virtual ~son(){cout<<"析构son"<<endl;}
virtual void beautiful(){cout<<"儿子也很帅"<<endl;}
virtual void smart(){cout<<"儿子也很聪明"<<endl;}
};
int main()
{
human *p;
int choice=0;
while(choice<99)
{
bool quit=false;
cout<<"(0)退出(1)父亲(2)儿子(3)母亲:";
cin>>choice;
switch(choice)
{
case 0:quit=true;
break;
case 1:p=new father;
p->beautiful();
p->smart();
delete p;
break;
case 2:p=new son;
p->beautiful();
p->smart();
delete p;
break;
case 3:p=new mother;
p->beautiful();
p->smart();
delete p;
break;
default:cout<<"请输入从0到2之间的数字。";
break;
}

if(quit)
{
break;
}
}
cout<<"程序结束"<<endl;
return 0;
}

3.2 输出结果

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
(0)退出(1)父亲(2)儿子(3)母亲:1
构造huamn
构造father
父亲不是很帅
父亲很聪明
析构father
析构human
(0)退出(1)父亲(2)儿子(3)母亲:2
构造huamn
构造father
构造mother
构造son
儿子也很帅
儿子也很聪明
析构son
析构mother
析构father
析构human
(0)退出(1)父亲(2)儿子(3)母亲:3
构造huamn
构造mother
母亲很漂亮。。
母亲并不聪明
析构mother
析构human
(0)退出(1)父亲(2)儿子(3)母亲:

四 说明

  • 由于抽象类不是实际存在的类,所以你不能定义一个抽象类的对象
  • Human *p=new Human;这样的做饭是错误的,因为抽象类创造出来的对象也是抽象的,这就好像你根据书本上的电视机这个词汇又创造一个名叫"p"的电视机词汇,这两者都是模糊的概念,不是实际存在的个体。因此你不能用这个p来调用它的成员函数
  • 你试图让你所创造的名叫p的电视机词汇来播放电视节目,很显然,这是不可能完成的任务,除非你能够让照片中的飞机飞上天
  • 虽然你不可以定义一个抽象类的对象,但是你却可以定义一个指向抽象类的指针
  • Human *p=new father;或human *p=new mother;这样是可以的,p既是一个指向抽象类的指针,同时又是一个指向基类的指针,因此在程序编译或运行时,这个指针可以动态地指向子类的对象,从而实现程序的多态性