抽象基类为什么不能创建对象?

抽象类是一种特殊的类,它被设计用来作为其他类的基类,不能实例化为对象。以下是关于抽象类和纯虚函数的详细解释:

1. 抽象类的定义:
  • 抽象类:带有纯虚函数的类称为抽象类。抽象类不能实例化对象,只能作为基类被继承。
  • 纯虚函数:一种没有实现的虚函数,其定义格式为:
    virtual <返回类型> <函数名>(<参数列表>) = 0;
    
2. 抽象类的作用:

抽象类的主要作用是定义一个接口,为派生类提供公共的根,使派生类实现这些接口。

3. 使用抽象类时的注意事项:
  • 抽象类只能用作基类,不能创建抽象类的对象。
  • 派生类如果没有实现基类的纯虚函数,该派生类仍然是一个抽象类。
  • 派生类实现了基类的所有纯虚函数后,才变成具体类,能够实例化对象。
4. 纯虚函数的引入原因:
  • 多态:为了实现多态特性,需要在基类中定义虚函数。
  • 合理性:基类自身生成对象在很多情况下是不合适的。例如,Animal 类可以派生出 Tiger 和 Peacock 等子类,但 Animal 本身不应生成对象。
示例代码:
#include <iostream>
using namespace std;

// 基类:Shape
class Shape {
public:
    // 纯虚函数,要求派生类一定要实现
    virtual void draw() const = 0;
    virtual double area() const = 0;
    // 虚析构函数确保派生类对象被正确销毁
    virtual ~Shape() {}
};

// 派生类:Circle
class Circle : public Shape {
public:
    Circle(double r) : radius(r) {}
    void draw() const override {
        cout << "Drawing a Circle." << endl;
    }
    double area() const override {
        return 3.14159 * radius * radius;
    }
private:
    double radius;
};

// 派生类:Rectangle
class Rectangle : public Shape {
public:
    Rectangle(double w, double h) : width(w), height(h) {}
    void draw() const override {
        cout << "Drawing a Rectangle." << endl;
    }
    double area() const override {
        return width * height;
    }
private:
    double width, height;
};

int main() {
    // 抽象类不能实例化对象
    // Shape shape; // 错误,Shape 是抽象类

    // 使用抽象类指针或引用指向具体类对象
    Shape* shapes[2];
    shapes[0] = new Circle(5);
    shapes[1] = new Rectangle(4, 6);

    for (int i = 0; i < 2; ++i) {
        shapes[i]->draw();
        cout << "Area: " << shapes[i]->area() << endl;
    }

    // 释放内存
    for (int i = 0; i < 2; ++i) {
        delete shapes[i];
    }

    return 0;
}
代码解析:
  • 纯虚函数
    • 在 Shape 基类中定义了两个纯虚函数 draw() 和 area(),表示 Shape 是一个抽象类。
  • 派生类的实现
    • Circle 和 Rectangle 类都是从 Shape 类派生出来的,并实现了纯虚函数 draw() 和 area()
  • 多态性
    • 在 main 函数中,使用 Shape 类指针数组来存储不同的 Shape 对象,体现了多态性。
    • 调用 draw() 和 area() 方法时,实际调用的时派生类实现的函数,演示了运行时的多态性。

通过这些内容和示例代码,我们展示了抽象类和纯虚函数的概念和应用,帮助你更好地理解为什么抽象类不能实例化,以及如何运用它们来实现多态性的设计模式

06-09 12:53