练习:使用多态容器统一处理图形¶
任务描述¶
使用 std::vector<std::unique_ptr<Shape>> 保存不同图形,并计算总面积。
相关知识¶
多态容器通常保存基类指针;unique_ptr 自动管理动态对象的生命周期。
为什么不能按值保存 Shape¶
Shape 是抽象类,不能作为 std::vector<Shape> 的元素类型;即使基类不是抽象类,按值保存不同派生对象也会产生对象切片。基类智能指针可同时避免这两个问题。
unique_ptr 的所有权¶
每个 unique_ptr<Shape> 独占一个图形对象。容器销毁时会自动释放其中所有图形,无需手写 delete。
编程要求¶
Shape提供纯虚函数area() const。- 向容器加入
Circle(1)与Rectangle(2, 3)。 - 完成
totalArea,返回3.14 + 6.0,并用assert验证。 totalArea接收const容器引用,遍历时只调用area(),不得修改容器。Shape必须有虚析构函数;Circle和Rectangle的area均使用override。
待完成代码¶
#include <cassert>
#include <iostream>
#include <memory>
#include <sstream>
#include <vector>
// TODO:定义 Shape、Circle、Rectangle 和 totalArea
void test() {
std::vector<std::unique_ptr<Shape>> shapes;
// TODO:添加两种图形
assert(totalArea(shapes) == 9.14);
std::ostringstream output;
std::streambuf* oldBuffer = std::cout.rdbuf(output.rdbuf());
std::cout << "总面积:" << totalArea(shapes) << '\n';
std::cout.rdbuf(oldBuffer);
assert(output.str() == "总面积:9.14\n");
}
int main() {
test();
std::cout << "本关测试通过" << std::endl;
return 0;
}
测试说明¶
容器中应恰好有两个对象。测试除断言总面积外,还验证输出 总面积:9.14;不得通过类型分支区分不同图形。
开始你的任务吧,祝你成功!