嗯,Hospital
是具有病人载体的类。
FemaleIn
,FemaleOut
,MaleIn
,MaleOut
是患者的派生类(基类)。这些类具有toString
函数(方法)。我想要做的是,在display
类的Hospital
方法中,我只想显示Outpatient
的父类FemaleOut
和{{} 1}}或Maleout
,它是Inpatient
和FemaleIn
的父类。从我所想的只调用特定方法,例如MaleIn
,我将不得不自动知道哪个对象在哪个矢量索引中。是否有任何想法仅针对特定类调用Outpatient
,例如toString
和FemaleIn
,其中父类为MaleIn
。感谢您的任何帮助或建议。
Inpatient
答案 0 :(得分:3)
我认为这个问题可能类似于How do I check if an object's type is a particular subclass in C++?。
我会建议像:
Class Patient{
virtual bool display(string filter);
};
Class OutPatient : Patient {
bool display(string filter) override;
};
bool OutPatient::display(string filter) {
if (filter != "OutPatient")
return false;
//Do stuff
return true;
}
Class InPatient : Patient {
bool display(string filter) override;
};
// You could just make this the default definition on display on Patient
bool InPatient::display(string filter) {
return false;
}
然后:
void Hospital::display(string type)
{
for(auto& patient: patients)
patient->display(type);
}
答案 1 :(得分:0)
以快速和脏的方式,您可以使用dynamic_cast
某个类指针来检测给定的实例是否属于该类:
if (type == "Outpatient")
{
for(int i=0; i<patients.size(); ++i)
{
// try to cast parent class pointer to one of child class
// if one is pointer to that child class p is not nullptr
// otherwise p is nullptr
Outpatient * p = dynamic_cast<Outpatient *>(patients[i]);
if (p) {
p->toString();
}
}
}
对于干净的方式,您可以使用Visitor pattern
访客模式实施:
#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <utility>
class AbstractDirectionPatientsDispatcher;
class AbstractGenderPatientDispatcher;
class Patient
{
public:
virtual void accept(AbstractDirectionPatientsDispatcher &dispatcher) = 0;
virtual void accept(AbstractGenderPatientDispatcher &dispatcher) = 0;
std::string name;
};
class InPatient;
class OutPatient;
class AbstractDirectionPatientsDispatcher {
public:
virtual void dispatch(InPatient &patient) = 0;
virtual void dispatch(OutPatient &patient) = 0;
};
class FemalePatient;
class MalePatient;
class AbstractGenderPatientDispatcher {
public:
virtual void dispatch(FemalePatient &patient) = 0;
virtual void dispatch(MalePatient &patient) = 0;
};
template <typename PatientClass, typename Dispatcher>
class CRTPDispatchApplier : virtual public Patient
{
public:
void accept(Dispatcher &dispatcher) override {
dispatcher.dispatch(static_cast<PatientClass &>(*this));
}
};
class InPatient : public CRTPDispatchApplier<InPatient, AbstractDirectionPatientsDispatcher>
{
};
class OutPatient : public CRTPDispatchApplier<OutPatient, AbstractDirectionPatientsDispatcher>
{
};
class FemalePatient : public CRTPDispatchApplier<FemalePatient, AbstractGenderPatientDispatcher>
{
};
class MalePatient : public CRTPDispatchApplier<MalePatient, AbstractGenderPatientDispatcher>
{
};
class InFemale : public FemalePatient, public InPatient
{
};
class OutFemale : public FemalePatient, public OutPatient
{
};
class InMale : public MalePatient, public InPatient
{
};
class OutMale : public MalePatient, public OutPatient
{
};
class DummyDirectionDispatecher : public AbstractDirectionPatientsDispatcher
{
public:
void dispatch(InPatient & ) override {
}
void dispatch(OutPatient & ) override {
}
};
class DummyGenderDispatcher : public AbstractGenderPatientDispatcher
{
public:
void dispatch(FemalePatient &) override {
}
void dispatch(MalePatient &) override {
}
};
template <typename Direction>
class DispatchByDirection : public DummyDirectionDispatecher
{
public:
DispatchByDirection(std::function<void(Direction &)> action) :
m_action(std::move(action))
{}
void dispatch(Direction & p) override {
m_action(p);
}
private:
std::function<void(Direction &)> m_action;
};
template <typename Gender>
class DispatchByGender : public DummyGenderDispatcher
{
public:
DispatchByGender(std::function<void(Gender &)> action) :
m_action(std::move(action))
{}
void dispatch(Gender & p) override {
m_action(p);
}
private:
std::function<void(Gender &)> m_action;
};
int main() {
InFemale f1;
OutFemale f2;
InMale m1;
OutMale m2;
f1.name = "Eve";
f2.name = "Alice";
m1.name = "Bob";
m2.name = "Charlie";
std::vector<Patient *> patients;
patients.push_back(&f1);
patients.push_back(&f2);
patients.push_back(&m1);
patients.push_back(&m2);
DispatchByDirection<InPatient> print_in_patients{[](InPatient &patient){
std::cout << "in: " << patient.name << std::endl;
}};
for (auto p : patients) {
p->accept(print_in_patients);
}
std::cout << std::endl;
DispatchByDirection<OutPatient> print_out_patients{[](OutPatient &patient) {
std::cout << "out: " << patient.name << std::endl;
}};
for (auto p : patients) {
p->accept(print_out_patients);
}
std::cout << std::endl;
DispatchByGender<FemalePatient> print_female{[](FemalePatient &patient) {
std::cout << "female: " << patient.name << std::endl;
}};
for (auto p : patients) {
p->accept(print_female);
}
std::cout << std::endl;
DispatchByGender<MalePatient> print_male{[](MalePatient &patient) {
std::cout << "male: " << patient.name << std::endl;
}};
for (auto p : patients) {
p->accept(print_male);
}
std::cout << std::endl;
}