教程 cpp tutorial

纯虚函数与抽象类

在 C++ 中,纯虚函数和抽象类是实现多态性和面向对象设计的重要工具。通过纯虚函数可以定义接口,并通过抽象类来规范派生类的行为。

纯虚函数

纯虚函数是没有函数体的虚函数,它在基类中声明,但不提供实现。纯虚函数的作用是强制要求派生类必须实现该函数。纯虚函数通过在函数声明末尾加 = 0 来标识。

纯虚函数的定义

cpp
class Shape {
public:
    // 纯虚函数
    virtual void draw() = 0;  
};

`

上面的例子中,draw() 函数是纯虚函数,它没有提供函数体。任何派生自 Shape 类的类都必须实现 draw() 函数,否则这些派生类也将是抽象类。

抽象类

包含纯虚函数的类被称为抽象类。抽象类无法直接实例化,也就是说,不能创建抽象类的对象。抽象类的主要作用是作为其他类的基类,定义接口并要求派生类实现特定的行为。

抽象类示例

cpp
#include <iostream>
using namespace std;

class Shape {
public:
    virtual void draw() = 0;  // 纯虚函数
    virtual ~Shape() {}  // 虚析构函数,确保派生类的析构函数正确调用
};

class Circle : public Shape {
public:
    void draw() override {  // 重写纯虚函数
        cout << "Drawing a circle." << endl;
    }
};

class Square : public Shape {
public:
    void draw() override {  // 重写纯虚函数
        cout << "Drawing a square." << endl;
    }
};

int main() {
    Shape* shape1 = new Circle();
    Shape* shape2 = new Square();

    shape1->draw();  // 输出: Drawing a circle.
    shape2->draw();  // 输出: Drawing a square.

    delete shape1;
    delete shape2;
    return 0;
}

输出:

代码
Drawing a circle.
Drawing a square.

在上面的代码中,Shape 类是一个抽象类,它定义了一个纯虚函数 draw()。Circle 和 Square 类继承自 Shape 并实现了 draw() 函数,因此它们可以创建对象并正常使用。

纯虚函数与抽象类的关系

  • 纯虚函数:它是没有实现的虚函数,要求派生类提供具体的实现。
  • 抽象类:包含至少一个纯虚函数的类,被称为抽象类。抽象类无法实例化,只能作为基类使用,派生类必须实现纯虚函数。

使用抽象类定义接口

抽象类可以作为接口使用,定义一组必须由派生类实现的函数。这种设计模式非常适用于定义通用接口,并允许不同的派生类根据需求来实现具体的行为。

cpp
class Drawable {
public:
    virtual void draw() = 0;  // 纯虚函数
    virtual void resize() = 0;  // 纯虚函数
};

在上面的例子中,Drawable 是一个接口,所有继承 Drawable 的类都必须实现 draw() 和 resize() 函数。

小结

  • 纯虚函数:是没有实现的虚函数,用 = 0 来标识,要求派生类必须实现该函数。
  • 抽象类:包含纯虚函数的类,不能实例化,只能作为基类供派生类继承并实现纯虚函数。
  • 抽象类与接口:抽象类可以被用作接口,规范派生类必须实现的行为。

通过纯虚函数和抽象类,C++ 提供了强大的多态性支持,允许设计灵活且可扩展的系统。