C++教程:C++抽象類與純虛函數
2020-05-23 14:25:22
供稿:網友
在本章開頭介紹的RPG游戲中共有4個類。其中玩家類作為父類,劍士類、弓箭手類、魔法師類分別繼承玩家類,作為子類。當我們開始游戲時,需要選擇創建某一個類的對象,才能進行游戲。然而,我們的選擇不應該是4個類,而應該只能在劍士類、弓箭手類或魔法師類中做出選擇。因為,單純的玩家類是抽象的、不完整的,任何一個玩家必須有一個確定的職業之后,才能確定他的具體技能。又比如學生類,它也是非常抽象的。讓一個小學生、中學生或本科生學習,他們都有各自學習的內容。而一個抽象概念的學生,他卻不知道該學些什么。
這時,我們必須要對玩家類或學生類作一些限制了。由于玩家類和學生類直接實例化而創建的對象都是抽象而沒有意義的,所以我們希望玩家類和學生類只能用于被繼承,而不能用于直接創建對象。在C++中,我們可以把只能用于被繼承而不能直接創建對象的類設置為抽象類(Abstract Class)。
之所以要存在抽象類,最主要是因為它具有不確定因素。我們把那些類中的確存在,但是在父類中無法確定具體實現的成員函數稱為純虛函數。純虛函數是一種特殊的虛函數,它只有聲明,沒有具體的定義。抽象類中至少存在一個純虛函數;存在純虛函數的類一定是抽象類。存在純虛函數是成為抽象類的充要條件。
那么我們該如何定義一個純虛函數呢?純虛函數的聲明有著特殊的語法格式:
virtual 返回值類型成員函數名(參數表)=0;
請注意,純虛函數應該只有聲明,沒有具體的定義,即使給出了純虛函數的定義也會被編譯器忽略。下面我們就修改一下程序17.7.1,將學生類變成一個抽象類:(程序17.9)
//student.h
#include <iostream>
using namespace std;
class student//因為存在純虛函數study,student類自動變成了抽象類
{
public:
student(char *n,int a,int h,int w);
student();
void set(char *n,int a,int h,int w);
char * sname();
int sage();
int sheight();
int sweight();
virtual void study()=0;//聲明study為純虛函數
protected:
char name[10];
int age;
int height;
int weight;
};
char * student::sname()
{
return name;
}
int student::sage()
{
return age;
}
int student::sheight()
{
return height;
}
int student::sweight()
{
return weight;
}
void student::set(char *n,int a,int h,int w)
{
int i;
for (i=0;n[i]!='/0';i++)
{
name[i]=n[i];
}
name[i]='/0';
age=a;
height=h;
weight=w;
return;
}
student::student(char *n,int a,int h,int w)
{
cout <<"Constructing a student with parameter..." <<endl;
set(n,a,h,w);
}
student::student()
{
cout <<"Constructing a student without parameter..." <<endl;
}
//undergraduate.h和pupil.h同程序17.7.1
//main.cpp
#include <iostream>
#include "undergraduate.h"
#include "pupil.h"
using namespace std;
int main()
{
Undergraduate s1;
/*student s2;//此時創建學生對象將會出現編譯錯誤*/
Pupil s3;
student *sp=&s1;
s1.set("Tom",21,178,60);
sp->study();
sp=&s3;
s3.set("Mike",8,148,45);
sp->study();
return 0;
}
運行結果:
Constructing a student without parameter...
Constructing a student without parameter...
學習高等數學和大學英語。
學習語數外。
我們看到,設置了純虛函數之后并不影響多態的實現,但是卻將父類變成了抽象類,限制了父類對象的創建。有了抽象類之后,就不會再出現不確定職業的玩家、不確定身份的學生了。