练习3:使用私有继承设计学生与研究生信息类¶
任务描述¶
设计 People、Student 和 Graduate 三个类,形成 People → Student → Graduate 的继承关系。其中 Student 私有继承 People,Graduate 公有继承 Student。
通过 Graduate 对象设置并输出姓名、学号和研究方向,理解私有继承如何限制基类接口在后续派生类和类外代码中的可见性。
相关知识¶
私有继承¶
私有继承的语法如下:
在私有继承中,People 的 public 和 protected 成员在 Student 中都成为私有成员。Student 的成员函数可以访问它们,但 Graduate 和类外代码不能直接访问这些继承成员。
通过 Student 重新开放受控接口¶
若 Graduate 需要使用人员姓名功能,Student 必须提供自己的公有包装函数:
class Student : private People {
public:
void setStudentName(const std::string& name) {
People::setName(name);
}
};
Graduate 虽不能直接访问 People::setName,但可继承并调用 Student::setStudentName。
多层继承与访问控制¶
本题的访问路径如下:
所有数据成员保持私有;类外代码只能通过各层对外公开的设置器、访问器和输出函数访问状态。
编程要求¶
- 使用 C++11 标准编写程序。将
People、Student、Graduate分别声明在People.h、Student.h、Graduate.h中,并在对应.cpp文件中实现成员函数。 People的私有成员为std::string name,提供:
Student使用private继承People,私有成员为int sid,提供:
void setSid(int sid);
int getSid() const;
void printSid() const;
void setStudentName(const std::string& name);
const std::string& getStudentName() const;
void printStudentName() const;
Graduate使用public继承Student,私有成员为int researchId,提供:
- 姓名包装函数由
Student调用其私有继承得到的People接口完成。不得定义题干中的独立Set函数。 - 在
test中通过Graduate对象的设置器赋值,使用assert验证三个访问器和输出结果。
待完成代码¶
People.h¶
Student.h¶
Graduate.h¶
People.cpp¶
Student.cpp¶
Graduate.cpp¶
main.cpp¶
#include "Graduate.h"
#include <cassert>
#include <iostream>
#include <sstream>
void test() {
Graduate graduate;
graduate.setSid(1);
graduate.setStudentName("厉宏富");
graduate.setResearchId(304);
assert(graduate.getSid() == 1);
assert(graduate.getStudentName() == "厉宏富");
assert(graduate.getResearchId() == 304);
std::ostringstream output;
std::streambuf* oldBuffer = std::cout.rdbuf(output.rdbuf());
graduate.printSid();
graduate.printStudentName();
graduate.printResearchId();
std::cout.rdbuf(oldBuffer);
assert(output.str() == "学号:1\n姓名:厉宏富\n研究方向:304\n");
}
int main() {
test();
std::cout << "本关测试通过" << std::endl;
return 0;
}
测试说明¶
设置学号 1、姓名 厉宏富、研究方向 304 后,预期输出为:
可使用以下命令编译:
开始你的任务吧,祝你成功!