You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者성기덕

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:31:10