在 C++ 中,抽象基類(Abstract Base Class, ABC) 是一種特殊的類,用于定義接口規范和約束派生類的行為。它通過純虛函數(Pure Virtual Function)強制要求派生類實現特定功能,自身不能被實例化。以下是抽象基類的核心概念和使用方法:
1. 定義抽象基類
抽象基類必須包含至少一個 純虛函數,語法為在虛函數聲明后添加 = 0
:
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. 抽象基類的特性
- 不可實例化:抽象基類不能直接創建對象。
Shape s; // 錯誤:無法實例化抽象類
- 強制派生類實現接口:派生類必須覆蓋所有純虛函數,否則仍是抽象類。
- 支持多態:通過基類指針或引用操作派生類對象。
3. 派生類實現示例
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. 使用抽象基類實現多態
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 起):
派生類可通過virtual void someFunction() const = 0 { /* 默認實現 */ }
BaseClass::someFunction()
調用默認實現。
6. 抽象基類 vs 接口
- 抽象基類:可以包含數據成員、普通成員函數和純虛函數。
- 接口(類似 Java):僅包含純虛函數(無數據成員和普通函數),但 C++ 中通過純抽象類模擬:
class ISerializable { public:virtual void serialize() const = 0;virtual void deserialize() = 0;virtual ~ISerializable() = default; };
總結
抽象基類是 C++ 實現多態和接口規范的核心工具,通過純虛函數強制派生類實現特定功能,確保代碼的一致性和可擴展性。它在設計模式(如工廠模式、策略模式)和大型項目架構中廣泛應用。