纯虚函数
在定义一个表示抽象概念的基类时,有时无法或者不需要给出某些成员函数的具体实现,函数的实现在派生类中完成,基类中这样的函数声明为纯虚函数。例如动物都有叫声,但是不同的动物叫声也不相同,因此不需要在动物类中实现描述叫声的函数,而只需保留一个接口,具体的实现在各派生类中完成。
与虚函数相比,纯虚函数没有函数体,其作用是在基类中为派生类保留一个函数接口,方便派生类根据需要对它实现,实现多态。
C++中纯虚函数的声明形式如下所示:
virtual 函数返回值类型 函数名(参数表) = 0;
从上述形式可以看出,虽然纯虚函数与虚函数都是用virtual关键字声明,但纯虚函数只有函数名而不具备函数功能,不可被调用,声明格式后面的“= 0”并不表示函数的返回值为0,只是以这样的形式说明该函数为纯虚函数,“= 0”后以分号结尾,表示声明结束。
若在一个类中声明了纯虚函数,但是在其派生类中没有实现该函数,则该函数在派生类中仍为纯虚函数。
接下来通过一个案例说明纯虚函数的定义,如例1所示。
例1
1 #include <iostream>
2 using namespace std;
3
4 class Animal //定义基类Animal
5 {
6 public:
7 Animal(char *name); //声明基类构造函数
8 void print_name(); //声明print_name()函数
9 virtual void print_color() = 0; //声明纯虚函数print_color()
10 virtual ~Animal(); //声明虚析构函数
11 private:
12 char *m_pAnimalName; //存放动物名称的数据成员
13 };
14
15 Animal::Animal(char *name) //Animal类构造函数的定义
16 {
17 int len = strlen(name) + 1;
18 m_pAnimalName = new char[len]; //为m_pAnimalName指针开辟空间
19 strcpy_s(m_pAnimalName, len, name); //存入动物名称
20 }
21 Animal::~Animal() //Animal类析构函数
22 {
23 cout << "Animal destructor!" << endl;
24 if (m_pAnimalName){
25 delete[]m_pAnimalName; //释放空间
26 }
27 }
28 void Animal::print_name() //定义print_name()函数
29 {
30 cout << "name:" << m_pAnimalName << endl;
31 }
32 class Cat:public Animal //定义派生类Cat
33 {
34 public:
35 Cat(char* name, char *catcolor);
36 virtual void print_color(); //声明虚函数print_color()
37 virtual ~Cat(); //声明虚析构函数
38 private:
39 char *m_pCatColor; //存放猫颜色的数据成员
40 };
41 Cat::Cat(char* name, char *color):Animal(name) //Cat类构造函数的定义
42 {
43 cout << "Cat constructor!" << endl;
44 m_pCatColor = new char[strlen(color) + 1]; //为m_pCatColor指针开辟空间
45 strcpy_s(m_pCatColor, strlen(color) + 1, color); //存入描述猫颜色的字符串
46 }
47 Cat::~Cat() //Cat类析构函数的定义
48 {
49 cout << "Cat destructor!" << endl;
50 if (m_pCatColor){
51 delete[]m_pCatColor; //释放m_pCatColor指向的空间
52 }
53 }
54 void Cat::print_color() //print_color()虚函数的实现
55 {
56 cout << "cat color :" << m_pCatColor << endl;
57 }
58 int main()
59 {
60 Animal *p; //定义基类Animal指针数组
61
62 p = new Cat("short_haired_cat", "white"); //通过new生成派生类Cat对象
63 p->print_name();
64 p->print_color();
65 cout << "--------------------" << endl;
66 delete p; //通过delete释放派生类对象
67 system("pause");
68 return 0;
69 }
运行结果如图1所示。
图1 例1运行结果
例1中第9行声明print_color()为纯虚函数,该函数在派生类Cat中给出了实现,如代码第54-57行。可以看到,通过声明纯虚函数,基类中只提供函数接口,派生类根据需要给出具体实现。