纯虚函数,一般是在设计一个基类时使用的,它将接口函数设置为纯虚函数后,只提供子类去继承并实现,以形成多态,除此以外不提供任何其他功能,我们称这种类为抽象类(abstract)。
【纯虚函数的声明语法】
virtual 函数声明 = 0;
【纯虚函数的特征】
1、只有声明,没有实现代码。
2、含有纯虚函数的类称为抽象类(abstract)。不能被实例化,只能被继承。
3、继承抽象类的意义就是提供族类的公共接口。
4、子类继承的纯虚函数,如果未实现,子类仍然为抽象类,仍然不能被实例化。
【虚函数的若干限制】
1、只有类的成员函数才能声明为虚函数。虚函数仅适用于有继承关系的类对象,所以普通函数不能声明为虚函数。
2、静态成员函数不能是虚函数静态成员函数不受对象的捆绑,只有类的信息。
3、内联函数不能是虚函数。
4、构造函数不能是虚函数,构造时,对象的创建尚未完成。构造完成后,能算一个名符其实的对象。
5、析构函数可以是虚函数且通常声明为虚函数。
【实现代码】
#include <iostream> using namespace std; class Shape { public: Shape(int x, int y) :_x(x), _y(y) { cout << "Shape constructor" << endl; } // 纯虚函数,初始化为 0,提供族类的公共接口 virtual void draw() = 0; ~Shape() { cout << "Shape destructor" << endl; } protected: int _x; int _y; }; class Rect : public Shape { public: Rect(int x, int y, int m) : Shape(x, y), _m(m){} // 子类若未实现父类纯虚函数,那么这个类也是抽象类,不能被实例化 private: int _m; }; // 继承 Shape 类 class Circle : public Shape { public: Circle(int x, int y, int r) :Shape(x, y), _r(r) { cout << "Circle constructor" << endl; } // 覆写父类 virtual 接口函数 void draw() { cout << "draw Circle "; cout << "start (" << _x << "," << _y << ") "; cout << "radio r = " << _r << endl; } ~Circle() { cout << "Circle destructor" << endl; } private: int _r; }; int main(int argc, char* argv[]) { // 抽象类不能实例化对象 // Shape s; // 子类若未实现父类纯虚函数,那么这个类也是抽象类,不能被实例化 // Rect r; // 使用子类对象初始化父类对象指针,构成多态 Shape *s = new Circle(2, 4, 8); s->draw(); // delete 指针,调用析构函数 delete s; return 0; }
以上代码演示了纯虚函数的定义,但上面代码存在一个问题,我们先看一下运行的结果。
class Shape { public: Shape(int x, int y) :_x(x), _y(y) { cout << "Shape constructor" << endl; } // 纯虚函数,初始化为 0,提供族类的公共接口 virtual void draw() = 0; // 增加 virtual 关键字,让其自动执行子类析构函数 virtual ~Shape() { cout << "Shape destructor" << endl; } protected: int _x; int _y; };
这样修改代码后,我们再次运行,结果就能看到,Circle 正常被析构了。