练习6:使用组合类模拟汽车发动机¶
任务描述¶
设计发动机类 Engine 和汽车类 Car。Car 对象包含一个 Engine 对象,通过汽车的启动、加速和熄火操作协调发动机状态,并输出汽车最终状态。
本题练习外层对象如何调用成员对象的函数,使多个类共同完成一项功能。
相关知识¶
组合关系中的职责划分¶
组合关系中,成员对象负责自身状态,外层对象负责组织整体行为。对于本题:
Engine负责记录发动机是否启动、当前转速;Car持有一个Engine对象,并将启动、加速、熄火等请求委托给发动机。
调用成员对象的函数¶
在 Car 的成员函数中,可以直接使用成员对象名调用其公有函数:
这里的 engine 是一个对象,不是指针,因此使用 . 而不是 ->。
状态变化¶
本题规定:发动机启动后转速为 800;每次加速使转速增加 500;熄火后转速变为 0。发动机未启动时调用加速不应改变转速。
编程要求¶
- 使用 C++11 标准编写程序。
- 在
Car.h中声明Engine类。它应提供以下公有成员函数:
- 在同一头文件中声明
Car类,并将Engine engine声明为私有成员。Car应提供:
- 在
Car.cpp中定义所有成员函数。Car的Start、Accelerate、Stop分别调用内部engine对象的对应函数。 PrintStatus按如下格式输出:
- 在
main.cpp中创建Car对象,测试启动和两次加速后的状态,以及熄火后的状态;使用assert对输出进行验证。
待完成代码¶
Car.h¶
Car.cpp¶
main.cpp¶
#include "Car.h"
#include <cassert>
#include <iostream>
#include <sstream>
void test() {
Car car;
car.Start();
car.Accelerate();
car.Accelerate();
std::ostringstream runningOutput;
std::streambuf* oldBuffer = std::cout.rdbuf(runningOutput.rdbuf());
car.PrintStatus();
std::cout.rdbuf(oldBuffer);
assert(runningOutput.str() == "发动机 ON\n转速 1800\n");
car.Stop();
std::ostringstream stoppedOutput;
oldBuffer = std::cout.rdbuf(stoppedOutput.rdbuf());
car.PrintStatus();
std::cout.rdbuf(oldBuffer);
assert(stoppedOutput.str() == "发动机 OFF\n转速 0\n");
}
int main() {
test();
std::cout << "本关测试通过" << std::endl;
return 0;
}
测试说明¶
发动机启动后转速为 800,两次加速后转速为 1800。熄火后,发动机状态应为 OFF,转速应归零。
可使用以下命令编译三个文件:
开始你的任务吧,祝你成功!