在 C++ 中,抽象基类(Abstract Base Class,ABC)是一种特殊的类,它主要用于作为其他类的基类,提供一个公共的接口。抽象基类不能被实例化,也就是不能创建抽象基类的对象,它的主要作用是为派生类定义一个统一的接口规范,派生类需要实现这些接口。下面详细介绍抽象基类的相关概念和使用方法。
纯虚函数
抽象基类的关键在于包含至少一个纯虚函数。纯虚函数是一种在基类中声明但没有实现的虚函数,它的声明方式是在虚函数声明的末尾加上 = 0
。
以下是纯虚函数的声明示例:
class Shape {
public:
// 纯虚函数,用于计算面积
virtual double area() const = 0;
};
在上述代码中,area()
函数是一个纯虚函数,它没有函数体,只有函数声明。
抽象基类的定义
只要一个类包含至少一个纯虚函数,那么这个类就是抽象基类。由于抽象基类包含纯虚函数,而纯虚函数没有实现,所以不能创建抽象基类的对象。
以下是一个抽象基类的完整示例:
#include <iostream>
// 抽象基类 Shape
class Shape {
public:
// 纯虚函数,用于计算面积
virtual double area() const = 0;
// 虚析构函数,确保正确释放派生类对象
virtual ~Shape() {}
};
// 派生类 Circle,继承自 Shape
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
// 实现纯虚函数 area()
double area() const override {
return 3.14159 * radius * radius;
}
};
// 派生类 Rectangle,继承自 Shape
class Rectangle : public Shape {
private:
double length;
double width;
public:
Rectangle(double l, double w) : length(l), width(w) {}
// 实现纯虚函数 area()
double area() const override {
return length * width;
}
};
int main() {
// 不能创建抽象基类 Shape 的对象
// Shape shape; // 编译错误
// 创建派生类对象
Circle circle(5.0);
Rectangle rectangle(4.0, 6.0);
// 通过基类指针调用派生类的 area() 函数
Shape* shape1 = &circle;
Shape* shape2 = &rectangle;
std::cout << "Circle area: " << shape1->area() << std::endl;
std::cout << "Rectangle area: " << shape2->area() << std::endl;
return 0;
}
代码解释
- 抽象基类
Shape
:包含一个纯虚函数area()
,因此Shape
是抽象基类。同时,为了确保在删除基类指针时能正确释放派生类对象,将析构函数声明为虚函数。 - 派生类
Circle
和Rectangle
:它们都继承自Shape
类,并且实现了纯虚函数area()
。 main
函数:尝试创建抽象基类Shape
的对象会导致编译错误。创建派生类Circle
和Rectangle
的对象,并通过基类指针调用派生类的area()
函数,实现了多态性。
抽象基类的作用
- 提供统一接口:抽象基类为派生类定义了一个统一的接口,派生类必须实现这些接口,从而保证了代码的一致性和规范性。
- 实现多态性:通过基类指针或引用调用派生类的函数,实现运行时多态,提高了代码的灵活性和可扩展性。