练习5:使用组合类表示学生生日¶
任务描述¶
设计日期类 Date 和学生类 Student。将 Date 对象作为 Student 的成员,用于保存学生生日,并输出完整的学生信息。
本题练习“类的组合”:一个类的对象作为另一个类的数据成员。Student 对象创建时,其内部的 Date 成员对象也会随之构造。
相关知识¶
类的组合¶
当一个类拥有另一个类的对象作为数据成员时,称为类的组合。例如,学生拥有一个生日日期:
birthday 是 Student 的组成部分,它的生命周期与所属的 Student 对象一致。
成员对象的初始化¶
如果成员对象没有无参构造函数,外层类必须在构造函数初始化列表中调用其构造函数:
Student::Student(const std::string& name, int year, int month, int day)
: name(name), birthday(year, month, day) {
}
成员对象的构造顺序由其在类中的声明顺序决定;析构时顺序相反。
委托成员对象完成工作¶
外层类可调用成员对象的公有成员函数。例如,Student::Print 可调用 birthday.Print() 输出生日。
编程要求¶
- 使用 C++11 标准编写程序。
- 在
Student.h中声明Date类,私有成员为year、month、day,并提供:
- 在同一头文件中声明
Student类,私有成员包括姓名和一个Date类型的生日成员:
Student应提供构造函数和Print函数:
- 在
Student.cpp中使用初始化列表构造Student的birthday成员。Date::Print输出年-月-日;Student::Print输出姓名和生日,格式见测试说明。 - 在
main.cpp中创建两个Student对象,捕获Print输出并用assert验证。
待完成代码¶
Student.h¶
Student.cpp¶
main.cpp¶
#include "Student.h"
#include <cassert>
#include <iostream>
#include <sstream>
void test() {
Student student1("李红霞", 2004, 5, 12);
Student student2("张如雪", 2003, 11, 8);
std::ostringstream output;
std::streambuf* oldBuffer = std::cout.rdbuf(output.rdbuf());
student1.Print();
student2.Print();
std::cout.rdbuf(oldBuffer);
assert(output.str() ==
"姓名 李红霞 生日 2004-5-12\n"
"姓名 张如雪 生日 2003-11-8\n");
}
int main() {
test();
std::cout << "本关测试通过" << std::endl;
return 0;
}
测试说明¶
Student::Print 应调用内部 Date 对象的输出功能。两名学生的预期输出为:
可使用以下命令编译三个文件:
开始你的任务吧,祝你成功!