侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

实现一个简单的图形绘制系统

2025-12-11 / 0 评论 / 8 阅读

题目

实现一个简单的图形绘制系统

信息

  • 类型:问答
  • 难度:⭐⭐

考点

继承与派生,虚函数与多态,纯虚函数与抽象类,动态内存管理

快速回答

实现要点:

  • 定义抽象基类Shape,包含纯虚函数draw()area()
  • 派生CircleRectangle类并重写虚函数
  • 使用基类指针容器管理不同图形对象
  • 正确实现深拷贝防止内存泄漏
  • 通过虚析构函数确保正确释放资源
## 解析

问题描述

设计一个图形系统,支持圆形和矩形两种图形。要求:

  1. 定义抽象基类Shape,包含纯虚函数virtual void draw() const = 0virtual double area() const = 0
  2. 实现派生类Circle(半径)和Rectangle(长宽)
  3. 创建drawAllShapes()函数,接收vector<Shape*>并调用各元素的draw()area()
  4. 实现深拷贝功能

代码实现

#include <iostream>
#include <vector>
#include <cmath>

// 抽象基类
class Shape {
public:
    virtual void draw() const = 0;
    virtual double area() const = 0;
    virtual Shape* clone() const = 0; // 克隆接口
    virtual ~Shape() {} // 虚析构函数
};

// 圆形派生类
class Circle : public Shape {
    double radius;
public:
    Circle(double r) : radius(r) {}

    void draw() const override {
        std::cout << "Drawing Circle with radius: " << radius 
                  << ", Area: " << area() << std::endl;
    }

    double area() const override {
        return 3.14159 * radius * radius;
    }

    Shape* clone() const override {
        return new Circle(*this); // 深拷贝
    }
};

// 矩形派生类
class Rectangle : public Shape {
    double width, height;
public:
    Rectangle(double w, double h) : width(w), height(h) {}

    void draw() const override {
        std::cout << "Drawing Rectangle " << width << "x" << height
                  << ", Area: " << area() << std::endl;
    }

    double area() const override {
        return width * height;
    }

    Shape* clone() const override {
        return new Rectangle(*this); // 深拷贝
    }
};

// 绘制所有图形
void drawAllShapes(const std::vector<Shape*>& shapes) {
    for (const auto& shape : shapes) {
        shape->draw(); // 多态调用
    }
}

// 深拷贝函数
std::vector<Shape*> cloneShapes(const std::vector<Shape*>& original) {
    std::vector<Shape*> clones;
    for (const auto& shape : original) {
        clones.push_back(shape->clone()); // 多态克隆
    }
    return clones;
}

// 释放内存
void deleteShapes(std::vector<Shape*>& shapes) {
    for (auto& shape : shapes) {
        delete shape; // 多态删除
    }
    shapes.clear();
}

核心原理

  • 多态机制:通过基类指针调用虚函数时,根据实际对象类型决定调用哪个版本的函数
  • 虚函数表:编译器为每个含虚函数的类创建vtable,存储函数指针
  • 抽象类:包含纯虚函数(=0)的类不能实例化,用于定义接口规范

最佳实践

  1. 基类析构函数必须声明为virtual,确保通过基类指针删除派生类对象时正确调用派生类析构函数
  2. 使用override关键字明确表示重写虚函数,避免意外隐藏
  3. 遵循Rule of Three:当需要自定义拷贝构造/赋值操作时,通常也需要自定义析构函数

常见错误

  • 内存泄漏:忘记释放new分配的对象
  • 对象切片:通过值传递派生类对象给基类参数时丢失派生类信息
  • 缺少虚析构函数:导致派生类资源泄漏
  • 浅拷贝问题:默认拷贝构造函数仅复制指针,导致重复释放

扩展知识

  • C++11智能指针:使用unique_ptr/shared_ptr自动管理内存
  • 工厂模式:通过工厂方法创建对象,隐藏具体类实现
  • typeid与dynamic_cast:运行时类型识别(RTTI)机制,但应优先使用多态