C++基类指针数组应用:医院类按患者类型分配派生类对象问题
实现多文件分离的医院患者类架构,支持动态派生类对象创建
我来帮你搞定这个多文件分离的医院类架构问题,按照要求把每个类拆到单独文件,同时实现Hospital根据患者类型创建对应派生类对象的功能。
第一步:文件结构划分
我们需要创建以下文件,每个类对应独立的头文件(.h),非纯虚类的实现放在对应的源文件(.cpp):
Patient.h:基类Patient的声明Male.h:派生类Male的声明Female.h:派生类Female的声明Inpatient.h:派生类Inpatient的声明Outpatient.h:派生类Outpatient的声明Hospital.h:Hospital类的声明Hospital.cpp:Hospital类的实现main.cpp:主测试函数
第二步:逐个实现文件内容
1. 基类 Patient(Patient.h)
这是抽象基类,定义所有患者的通用属性和纯虚接口:
#ifndef PATIENT_H #define PATIENT_H #include <string> class Patient { protected: std::string name; int age; public: Patient(const std::string& n, int a) : name(n), age(a) {} virtual ~Patient() = default; // 虚析构函数,确保派生类析构被调用 virtual void showInfo() const = 0; // 纯虚函数,强制派生类实现 virtual std::string getType() const = 0; // 获取患者类型 }; #endif
2. 派生类 Male(Male.h)
#ifndef MALE_H #define MALE_H #include "Patient.h" class Male : public Patient { public: Male(const std::string& n, int a) : Patient(n, a) {} void showInfo() const override { std::cout << "Male Patient: " << name << ", Age: " << age << std::endl; } std::string getType() const override { return "male"; } }; #endif
3. 派生类 Female(Female.h)
#ifndef FEMALE_H #define FEMALE_H #include "Patient.h" class Female : public Patient { public: Female(const std::string& n, int a) : Patient(n, a) {} void showInfo() const override { std::cout << "Female Patient: " << name << ", Age: " << age << std::endl; } std::string getType() const override { return "female"; } }; #endif
4. 派生类 Inpatient(Inpatient.h)
住院患者额外包含病房号属性:
#ifndef INPATIENT_H #define INPATIENT_H #include "Patient.h" class Inpatient : public Patient { private: std::string wardNumber; public: Inpatient(const std::string& n, int a, const std::string& ward) : Patient(n, a), wardNumber(ward) {} void showInfo() const override { std::cout << "Inpatient: " << name << ", Age: " << age << ", Ward: " << wardNumber << std::endl; } std::string getType() const override { return "inpatient"; } }; #endif
5. 派生类 Outpatient(Outpatient.h)
门诊患者额外包含预约日期属性:
#ifndef OUTPATIENT_H #define OUTPATIENT_H #include "Patient.h" class Outpatient : public Patient { private: std::string appointmentDate; public: Outpatient(const std::string& n, int a, const std::string& date) : Patient(n, a), appointmentDate(date) {} void showInfo() const override { std::cout << "Outpatient: " << name << ", Age: " << age << ", Appointment Date: " << appointmentDate << std::endl; } std::string getType() const override { return "outpatient"; } }; #endif
6. Hospital 类声明(Hospital.h)
用vector<Patient*>存储患者指针,实现动态添加和管理:
#ifndef HOSPITAL_H #define HOSPITAL_H #include "Patient.h" #include <vector> #include <string> class Hospital { private: std::vector<Patient*> patients; public: ~Hospital(); // 析构函数清理内存 // 根据类型添加患者,extraInfo用于住院/门诊的额外信息 bool addPatient(const std::string& type, const std::string& name, int age, const std::string& extraInfo = ""); // 显示所有患者信息 void showAllPatients() const; }; #endif
7. Hospital 类实现(Hospital.cpp)
这里核心是根据患者类型动态创建对应派生类对象:
#include "Hospital.h" #include "Male.h" #include "Female.h" #include "Inpatient.h" #include "Outpatient.h" #include <iostream> Hospital::~Hospital() { // 手动清理所有动态分配的患者对象,避免内存泄漏 for (Patient* p : patients) { delete p; } patients.clear(); } bool Hospital::addPatient(const std::string& type, const std::string& name, int age, const std::string& extraInfo) { Patient* newPatient = nullptr; // 根据类型匹配创建对应派生类对象 if (type == "male") { newPatient = new Male(name, age); } else if (type == "female") { newPatient = new Female(name, age); } else if (type == "inpatient") { if (extraInfo.empty()) { std::cerr << "Error: Inpatient needs a ward number!" << std::endl; return false; } newPatient = new Inpatient(name, age, extraInfo); } else if (type == "outpatient") { if (extraInfo.empty()) { std::cerr << "Error: Outpatient needs an appointment date!" << std::endl; return false; } newPatient = new Outpatient(name, age, extraInfo); } else { std::cerr << "Error: Unknown patient type - " << type << std::endl; return false; } if (newPatient) { patients.push_back(newPatient); return true; } return false; } void Hospital::showAllPatients() const { std::cout << "\n=== Hospital Patient List ===" << std::endl; for (const Patient* p : patients) { p->showInfo(); // 多态调用对应派生类的showInfo } }
8. 主测试函数(main.cpp)
#include "Hospital.h" int main() { Hospital cityHospital; // 添加不同类型的患者 cityHospital.addPatient("male", "John Doe", 30); cityHospital.addPatient("female", "Jane Smith", 28); cityHospital.addPatient("inpatient", "Bob Brown", 45, "Ward 3A"); cityHospital.addPatient("outpatient", "Alice Lee", 22, "2024-05-20"); // 显示所有患者信息 cityHospital.showAllPatients(); return 0; }
关键要点说明
- 头文件保护:每个头文件都用
#ifndef/#define/#endif包裹,防止重复包含导致编译错误。 - 多态实现:基类
Patient的虚函数和纯虚函数确保派生类的showInfo能被正确调用,实现多态行为。 - 内存管理:
Hospital的析构函数手动清理所有动态分配的患者对象,避免内存泄漏。 - 动态对象创建:在
addPatient方法中,根据传入的类型字符串动态实例化对应派生类,满足需求。
内容的提问来源于stack exchange,提问作者성기덕
相关产品推荐
相关产品推荐

