在C++中,纯虚函数是用来定义接口的一种方法。它们通常用于抽象基类(Abstract Base Class,简称ABC),这样的基类是不能实例化的,也就是说你不能创建它的对象。它的主要目的是允许派生类在继承了这个基类后,根据自己的需要来重写(override)这些纯虚函数。
使用纯虚函数的场景包括:
- 当你想要定义一个有通用接口的基类,但是实现细节要留给派生类时。
- 当基类本身的某个行为没有默认实现,或者没有实现的意义时。
- 为了强制派生类遵循某个特定的协议,即实现特定的函数集。
**
下面是一个使用纯虚函数的例子:
**
假设我们正在设计一个图形处理程序,所有的图形都可以绘制自己,并计算自己的面积。但是,对于“图形”这个概念,我们并不想实现具体的绘制方法和面积计算方法,因为这依赖于图形的具体类型(比如矩形、圆形等)。因此,我们可以创建一个包含纯虚函数的抽象基类:
#include <iostream>
// 抽象基类
class Shape {
public:
// 纯虚函数
virtual void draw() const = 0;
virtual double area() const = 0;
// 虚析构函数,确保派生类的析构函数被调用
virtual ~Shape() {}
};
// 派生类:矩形
class Rectangle : public Shape {
private:
double width;
double height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
void draw() const override {
std::cout << "Drawing a rectangle." << std::endl;
}
double area() const override {
return width * height;
}
};
// 派生类:圆形
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() const override {
std::cout << "Drawing a circle." << std::endl;
}
double area() const override {
return 3.14159 * radius * radius;
}
};
int main() {
// 因为Shape是抽象类,所以不能直接实例化
// Shape s; // 错误
// 创建派生类对象
Rectangle rect(10, 5);
Circle circle(7);
// 通过基类指针操作对象
Shape *shapes[2] = {&rect, &circle};
for (const Shape *shape : shapes) {
shape->draw();
std::cout << "Area: " << shape->area() << std::endl;
}
return 0;
}
在这个例子中,Shape
是一个抽象基类,它定义了两个纯虚函数:draw()
和 area()
。派生类 Rectangle
和 Circle
分别实现了这些函数,提供了绘制矩形和圆形以及计算面积的具体实现。在 main()
函数中,我们通过基类指针来操作不同的图形对象,并调用它们的 draw()
和 area()
函数。
纯虚函数的语法是在函数声明的末尾加上 = 0
。这表示该函数没有定义(即没有函数体),并且派生类必须提供实现。如果派生类没有重写所有的纯虚函数,则它也将成为一个抽象类,不能实例化。