深入解析深入解析C++编程中的纯虚函数和抽象类编程中的纯虚函数和抽象类
C++纯虚函数详解纯虚函数详解
有时在基类中将某一成员函数定为虚函数,并不是基类本身的要求,而是考虑到派生类的需要,在基类中预留了一个函数名,
具体功能留给派生类根据需要去定义。
纯虚函数是在声明虚函数时被“初始化”为0的函数。声明纯虚函数的一般形式是
virtual 函数类型 函数名 (参数表列) = 0;
关于纯虚函数需要注意的几点:
纯虚函数没有函数体;
最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”;
这是一个声明语句,最后应有分号。
纯虚函数只有函数的名字而不具备函数的功能,不能被调用。它只是通知编译系统:“在这里声明一个虚函数,留待派生类中定
义”。在派生类中对此函数提供定义后,它才能具备函数的功能,可被调用。
纯虚函数的作用是在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。
如果在基类中没有保留函数名字,则无法实现多态性。如果在一个类中声明了纯虚函数,而在其派生类中没有对该函数定义,
则该虚函数在派生类中仍然为纯虚函数。
再谈再谈C++抽象类抽象类
如果声明了一个类,一般可以用它定义对象。但是在面向对象程序设计中,往往有一些类,它们不用来生成对象。定义这些类
的惟一目的是用它作为基类去建立派生类。它们作为一种基本类型提供给用户,用户在这个基础上根据自己的需要定义出功能
各异的派生类。用这些派生类去建立对象。
打个比方,汽车制造厂往往向客户提供卡车的底盘(包括发动机、传动部分、车轮等),组装厂可以把它组装成货车、公共汽
车、工程车或客车等不同功能的车辆。底盘本身不是车辆,要经过加工才能成为车辆,但它是车辆的基本组成部分。它相当于
基类。在现代化的生产中,大多采用专业化的生产方式,充分利用专业化工厂生产的部件,加工集成为新品种的产品。生产公
共汽车的厂家决不会从制造发动机到生产轮胎、制造车厢都由本厂完成。其实,不同品牌的电脑里面的基本部件是一样的或相
似的。这种观念对软件开发是十分重要的。一个优秀的软件工作者在开发一个大的软件时,决不会从头到尾都由自己编写程序
代码,他会充分利用已有资源(例如类库)作为自己工作的基础。
这种不用来定义对象而只作为一种基本类型用作继承的类,称为抽象类(abstract class ),由于它常用作基类,通常称为抽象
基类(abstract base class )。凡是包含纯虚函数的类都是抽象类。因为纯虚函数是不能被调用的,包含纯虚函数的类是无法建
立对象的。
抽象类的作用是作为一个类族的共同基类,或者说,为一个类族提供一个公共接口。一个类层次结构中当然也可不包含任何抽
象类,每一层次的类都是实际可用的,可以用来建立对象的。
但是,许多好的面向对象的系统,其层次结构的顶部是一个抽象类,甚至顶部有好几层都是抽象类。
如果在抽象类所派生出的新类中对基类的所有纯虚函数进行了定义,那么这些函数就被赋予了功能,可以被调用。这个派生类
就不是抽象类,而是可以用来定义对象的具体类(concrete class )。
如果在派生类中没有对所有纯虚函数进行定义,则此派生类仍然是抽象类,不能用来定义对象。虽然抽象类不能定义对象(或
者说抽象类不能实例化),但是可以定义指向抽象类数据的指针变量。当派生类成为具体类之后,就可以用这种指针指向派生
类对象,然后通过该指针调用虚函数,实现多态性的操作。
几个关于几个关于C++纯虚函数与抽象类的实例纯虚函数与抽象类的实例
下面是一个完整的程序,为了便于阅读,分段插入了一些文字说明。程序如下:
第(1)部分
#include <iostream>
using namespace std;
//声明抽象基类Shape
class Shape
{
public:
virtual float area( )const {return 0.0;} //虚函数
virtual float volume()const {return 0.0;} //虚函数
virtual void shapeName()const =0; //纯虚函数
};
Shape类有3个成员函数,没有数据成员。3个成员函数都声明为虚函数,其中shapeName声明为纯虚函数,因此Shape是一