1. 通过多态实现对不同图形统一操作的示例代码
#include <iostream>
#include <cmath>
// 抽象图形类
class Shape {
public:
// 纯虚函数,计算面积
virtual double calculateArea() const = 0;
// 纯虚函数,显示图形信息
virtual void displayInfo() const = 0;
// 析构函数声明为虚函数,确保正确的析构顺序
virtual ~Shape() {}
};
// 圆形类,继承自Shape
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double calculateArea() const override {
return M_PI * radius * radius;
}
void displayInfo() const override {
std::cout << "Circle with radius " << radius << std::endl;
}
};
// 矩形类,继承自Shape
class Rectangle : public Shape {
private:
double width;
double height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double calculateArea() const override {
return width * height;
}
void displayInfo() const override {
std::cout << "Rectangle with width " << width << " and height " << height << std::endl;
}
};
// 三角形类,继承自Shape
class Triangle : public Shape {
private:
double base;
double height;
public:
Triangle(double b, double h) : base(b), height(h) {}
double calculateArea() const override {
return 0.5 * base * height;
}
void displayInfo() const override {
std::cout << "Triangle with base " << base << " and height " << height << std::endl;
}
};
int main() {
// 创建不同图形的指针数组
Shape* shapes[3];
shapes[0] = new Circle(5.0);
shapes[1] = new Rectangle(4.0, 6.0);
shapes[2] = new Triangle(3.0, 8.0);
// 遍历数组,调用统一的接口
for (int i = 0; i < 3; ++i) {
shapes[i]->displayInfo();
std::cout << "Area: " << shapes[i]->calculateArea() << std::endl;
delete shapes[i]; // 记得释放内存
}
return 0;
}
2. 抽象类在这种代码架构下的优点
- 代码复用性:抽象类提供了一个通用的接口,不同的具体图形类继承自抽象类,复用了抽象类的接口定义,减少了重复代码。例如所有图形类都有
calculateArea
和 displayInfo
方法,通过继承抽象类统一提供。
- 可扩展性:当需要添加新的图形类型时,只需要创建一个新的类继承自抽象图形类,并实现其纯虚函数即可,不需要修改现有代码。例如添加一个椭圆形类,只需要继承
Shape
并实现 calculateArea
和 displayInfo
。
- 多态性支持:通过抽象类和虚函数,实现了多态。可以使用基类指针或引用来操作不同的派生类对象,提高了代码的灵活性。如上述代码中通过
Shape*
数组操作不同的图形对象。
3. 可能面临的问题
- 增加代码复杂度:引入抽象类和虚函数机制会增加代码的复杂性,对于初学者理解和维护代码难度增加。例如虚函数表和动态绑定机制。
- 运行时性能开销:由于多态是通过虚函数表和动态绑定实现的,在运行时需要根据对象的实际类型来确定调用哪个函数,这会带来一定的性能开销,尤其是在性能敏感的应用中。
- 抽象类设计难度:设计一个合适的抽象类需要对整个项目有深入的理解,如果抽象类设计不合理,可能导致后续扩展困难,或者代码耦合度过高。例如如果抽象类的接口定义不符合实际需求,可能需要对所有派生类进行修改。