C++抽象基类定义与使用

在 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. 抽象基类的特性

  • 不可实例化 :抽象基类不能直接创建对象。

    cpp 复制代码
    Shape 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 起):

    cpp 复制代码
    virtual void someFunction() const = 0 { /* 默认实现 */ }

    派生类可通过 BaseClass::someFunction() 调用默认实现。


6. 抽象基类 vs 接口

  • 抽象基类:可以包含数据成员、普通成员函数和纯虚函数。

  • 接口 (类似 Java):仅包含纯虚函数(无数据成员和普通函数),但 C++ 中通过纯抽象类模拟:

    cpp 复制代码
    class ISerializable {
    public:
        virtual void serialize() const = 0;
        virtual void deserialize() = 0;
        virtual ~ISerializable() = default;
    };

总结

抽象基类是 C++ 实现多态和接口规范的核心工具,通过纯虚函数强制派生类实现特定功能,确保代码的一致性和可扩展性。它在设计模式(如工厂模式、策略模式)和大型项目架构中广泛应用。

相关推荐
Dxy12393102167 小时前
Python 使用正则表达式将多个空格替换为一个空格
开发语言·python·正则表达式
故事和你918 小时前
洛谷-数据结构1-1-线性表1
开发语言·数据结构·c++·算法·leetcode·动态规划·图论
脱氧核糖核酸__8 小时前
LeetCode热题100——53.最大子数组和(题解+答案+要点)
数据结构·c++·算法·leetcode
脱氧核糖核酸__9 小时前
LeetCode 热题100——42.接雨水(题目+题解+答案)
数据结构·c++·算法·leetcode
techdashen9 小时前
Rust项目公开征测:Cargo 构建目录新布局方案
开发语言·后端·rust
星空椰9 小时前
JavaScript 进阶基础:函数、作用域与常用技巧总结
开发语言·前端·javascript
忒可君9 小时前
C# winform 自制分页功能
android·开发语言·c#
Rust研习社10 小时前
Rust 智能指针 Cell 与 RefCell 的内部可变性
开发语言·后端·rust
王老师青少年编程10 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【线性扫描贪心】:数列分段 Section I
c++·算法·编程·贪心·csp·信奥赛·线性扫描贪心
王老师青少年编程10 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【线性扫描贪心】:分糖果
c++·算法·贪心算法·csp·信奥赛·线性扫描贪心·分糖果