跳转至

练习:使用抽象图形类计算面积


任务描述

设计抽象图形基类 Shape、矩形类 Rectangle 和圆形类 Circle。通过 Shape* 指针调用派生类重写的 PrintArea,输出对应图形的面积。

相关知识

纯虚函数

纯虚函数在基类中只定义接口,不提供可直接使用的功能:

virtual void PrintArea() const = 0;

= 0 表示函数是纯虚函数。派生类必须覆盖它,否则派生类仍是抽象类,不能创建对象。

抽象类

包含纯虚函数的 Shape 是抽象类,不能直接定义对象:

// Shape shape;  // 错误:抽象类不能实例化

但可以定义 Shape* 指针并指向 RectangleCircle 等具体派生类对象,以统一接口实现多态。

通过基类指针调用派生类实现

PrintArea 声明为虚函数时,通过基类指针调用会执行实际对象对应的覆盖版本:

Shape* shape = new Rectangle(10.0f, 2.0f);
shape->PrintArea();  // 调用 Rectangle::PrintArea
delete shape;

基类析构函数也应为虚函数,确保通过 Shape* 删除派生对象时能够正确析构。

编程要求

  1. 使用 C++11 标准编写单文件程序。
  2. 声明抽象基类 Shape,包含:
virtual void PrintArea() const = 0;
virtual ~Shape() = default;
  1. 声明 Rectangle : public Shape,私有成员为 float widthfloat height,并实现:
Rectangle(float w, float h);
void PrintArea() const override;

输出格式为 矩形面积 = 数值,面积为 width * height

  1. 声明 Circle : public Shape,私有成员为 float radius,并实现:
explicit Circle(float r);
void PrintArea() const override;

输出格式为 圆形面积 = 数值,面积为 radius * radius * 3.14

  1. test 中分别通过 Shape* 创建、调用并删除矩形和圆形对象,捕获输出后使用 assert 验证结果。

待完成代码

#include <cassert>
#include <iostream>
#include <sstream>

class Shape {
public:
    // TODO:声明纯虚函数 PrintArea 和虚析构函数
};

class Rectangle : public Shape {
private:
    float width;
    float height;

public:
    // TODO:实现构造函数和 PrintArea
};

class Circle : public Shape {
private:
    float radius;

public:
    // TODO:实现构造函数和 PrintArea
};

void test() {
    Shape* rectangle = new Rectangle(10.0f, 2.0f);
    Shape* circle = new Circle(10.0f);

    std::ostringstream output;
    std::streambuf* oldBuffer = std::cout.rdbuf(output.rdbuf());
    rectangle->PrintArea();
    circle->PrintArea();
    std::cout.rdbuf(oldBuffer);

    delete rectangle;
    delete circle;

    assert(output.str() == "矩形面积 = 20\n圆形面积 = 314\n");

    Shape* smallRectangle = new Rectangle(2.0f, 2.0f);
    Shape* smallCircle = new Circle(2.0f);

    std::ostringstream smallOutput;
    oldBuffer = std::cout.rdbuf(smallOutput.rdbuf());
    smallRectangle->PrintArea();
    smallCircle->PrintArea();
    std::cout.rdbuf(oldBuffer);

    delete smallRectangle;
    delete smallCircle;

    assert(smallOutput.str() == "矩形面积 = 4\n圆形面积 = 12.56\n");
}

int main() {
    test();
    std::cout << "本关测试通过" << std::endl;
    return 0;
}

测试说明

第一组使用矩形 10 × 2 和半径为 10 的圆,预期输出:

矩形面积 = 20
圆形面积 = 314

第二组使用矩形 2 × 2 和半径为 2 的圆,预期输出:

矩形面积 = 4
圆形面积 = 12.56

原题中的第一组“10 2.5”与预期面积 20314 无法同时成立。本练习将图形尺寸明确为可验证的参数。


开始你的任务吧,祝你成功!