在 C++ 中,抽象基类(Abstract Base Class, ABC) 是一种特殊的类,用于定义接口规范和约束派生类的行为。它通过纯虚函数(Pure Virtual Function)强制要求派生类实现特定功能,自身不能被实例化。以下是抽象基类的核心概念和使用方法:
1. 定义抽象基类
抽象基类必须包含至少一个 纯虚函数 ,语法为在虚函数声明后添加 = 0
:
cpp
class Shape {
public:
// 纯虚函数:没有实现,必须由派生类覆盖
virtual double area() const = 0;
virtual double perimeter() const = 0;
// 普通虚函数(可选,可提供默认实现)
virtual void printInfo() const {
std::cout << "This is a shape." << std::endl;
}
// 虚析构函数(必须!确保正确释放资源)
virtual ~Shape() = default;
};
2. 抽象基类的特性
-
不可实例化 :抽象基类不能直接创建对象。
cppShape s; // 错误:无法实例化抽象类
-
强制派生类实现接口:派生类必须覆盖所有纯虚函数,否则仍是抽象类。
-
支持多态:通过基类指针或引用操作派生类对象。
3. 派生类实现示例
cpp
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
// 必须实现基类的纯虚函数
double area() const override {
return 3.14159 * radius * radius;
}
double perimeter() const override {
return 2 * 3.14159 * radius;
}
// 可覆盖基类的普通虚函数(可选)
void printInfo() const override {
std::cout << "This is a circle." << std::endl;
}
};
4. 使用抽象基类实现多态
cpp
int main() {
Shape* shape = new Circle(5.0);
// 调用派生类实现的函数
std::cout << "Area: " << shape->area() << std::endl; // 输出圆的面积
std::cout << "Perimeter: " << shape->perimeter() << std::endl;
shape->printInfo(); // 调用派生类的 printInfo()
delete shape;
return 0;
}
5. 关键注意事项
-
虚析构函数:基类的析构函数必须声明为虚函数,确保正确释放派生类资源。
-
接口规范:抽象基类用于定义通用接口,强制派生类遵守统一行为。
-
纯虚函数的默认实现 (C++11 起):
cppvirtual void someFunction() const = 0 { /* 默认实现 */ }
派生类可通过
BaseClass::someFunction()
调用默认实现。
6. 抽象基类 vs 接口
-
抽象基类:可以包含数据成员、普通成员函数和纯虚函数。
-
接口 (类似 Java):仅包含纯虚函数(无数据成员和普通函数),但 C++ 中通过纯抽象类模拟:
cppclass ISerializable { public: virtual void serialize() const = 0; virtual void deserialize() = 0; virtual ~ISerializable() = default; };
总结
抽象基类是 C++ 实现多态和接口规范的核心工具,通过纯虚函数强制派生类实现特定功能,确保代码的一致性和可扩展性。它在设计模式(如工厂模式、策略模式)和大型项目架构中广泛应用。