面试题答案
一键面试1. C++ 代码实现
#include <vector>
#include <iostream>
// 抽象基类,代表图形对象
class Shape {
public:
virtual double calculateArea() const = 0;
virtual ~Shape() = default;
};
// 三角形类,继承自 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;
}
};
// 计算图形对象集合总面积的函数
double calculateTotalArea(const std::vector<Shape*>& shapes) {
double totalArea = 0;
for (const auto& shape : shapes) {
totalArea += shape->calculateArea();
}
return totalArea;
}
可以这样调用函数:
int main() {
std::vector<Shape*> shapes;
shapes.push_back(new Triangle(3, 4));
shapes.push_back(new Triangle(5, 6));
double total = calculateTotalArea(shapes);
std::cout << "Total area: " << total << std::endl;
// 记得释放内存
for (auto shape : shapes) {
delete shape;
}
return 0;
}
2. 返回普通类型的优势
- 简单直观:返回普通类型(如
double
)使得调用者可以直接获取总面积数值,无需关心复杂的对象结构。例如在上述main
函数中,调用calculateTotalArea
后可以直接使用返回值进行进一步计算或展示,而不需要额外解析复杂对象的属性。 - 减少开销:返回复杂对象可能涉及对象的构造、析构以及可能的内存分配和释放操作。普通类型(如基本数据类型
double
)的传递通常是高效的,只需要复制一个固定大小的值,避免了复杂对象相关的额外开销。
3. 性能优化措施
- 避免不必要的复制:在
calculateTotalArea
函数中,通过const std::vector<Shape*>&
来接收图形对象集合,避免了整个集合的复制,减少了内存和时间开销。 - 虚函数优化:虽然使用了虚函数
calculateArea
来实现多态,但现代编译器通常会对虚函数调用进行优化,例如通过虚函数表的快速查找。同时,如果图形对象类型有限且固定,可以考虑使用switch - case
结合类型标识的方式(牺牲一定的代码灵活性)来进一步优化函数调用,减少虚函数调用的间接开销。 - 内存管理优化:在调用
calculateTotalArea
后,需要及时释放图形对象的内存(如在示例main
函数中)。可以考虑使用智能指针(如std::unique_ptr
或std::shared_ptr
)来管理图形对象的内存,避免手动释放内存可能导致的内存泄漏问题,同时智能指针的实现通常也有一定的性能优化。