如何在 C++ 中检查 vector 中的哪些对象
How to check which objects in vector in C++
嗯,Hospital
是 class,其中包含患者向量。
FemaleIn
、FemaleOut
、MaleIn
、MaleOut
源自 class 患者(基础 class)。那些 classes 有 toString
功能(方法)。我想做的是,在 Hospital
class 中的 display
方法中,我只想显示 Outpatient
的父级 class FemaleOut
和 Maleout
或 Inpatient
是 FemaleIn
和 MaleIn
的父级 class。根据我的想法,仅调用来自 Outpatient
的特定方法,我将不得不自动知道哪些对象在哪个向量索引中。有没有什么想法只为特定的 class 调用 toString
,例如,FemaleIn
和 MaleIn
,其中父 class 是 Inpatient
。感谢您的任何帮助或建议。
void Hospital::determinePatientType()
{
int selection;
cout << endl;
cout << "What is the patient type?" << endl;
cout << "1. Female Inpatient" << endl;
cout << "2. Female Outpatient" << endl;
cout << "3. Male Inpatient" << endl;
cout << "4. Male Outpatient" << endl;
cout << endl;
cin >> selection;
switch(selection)
{
case 1:
patients.push_back(new FemaleIn());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 2:
patients.push_back(new FemaleOut());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 3:
patients.push_back(new MaleIn());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 4:
patients.push_back(new MaleOut());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
default:
return;
}
}
void Hospital::display(string type)
{
cout << "Patient Name Spouse Name Sex Patient Type Unit/Appt. Date Diagnosis" << endl;
cout << "===================================================================================" << endl;
if(type=="All")
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
else if(type=="Outpatient")
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
else
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
}
您可以使用 dynamic_cast
到某些 class 指针来检测给定实例是否属于 class:
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;
}
我认为这个问题可能与 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);
}
嗯,Hospital
是 class,其中包含患者向量。
FemaleIn
、FemaleOut
、MaleIn
、MaleOut
源自 class 患者(基础 class)。那些 classes 有 toString
功能(方法)。我想做的是,在 Hospital
class 中的 display
方法中,我只想显示 Outpatient
的父级 class FemaleOut
和 Maleout
或 Inpatient
是 FemaleIn
和 MaleIn
的父级 class。根据我的想法,仅调用来自 Outpatient
的特定方法,我将不得不自动知道哪些对象在哪个向量索引中。有没有什么想法只为特定的 class 调用 toString
,例如,FemaleIn
和 MaleIn
,其中父 class 是 Inpatient
。感谢您的任何帮助或建议。
void Hospital::determinePatientType()
{
int selection;
cout << endl;
cout << "What is the patient type?" << endl;
cout << "1. Female Inpatient" << endl;
cout << "2. Female Outpatient" << endl;
cout << "3. Male Inpatient" << endl;
cout << "4. Male Outpatient" << endl;
cout << endl;
cin >> selection;
switch(selection)
{
case 1:
patients.push_back(new FemaleIn());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 2:
patients.push_back(new FemaleOut());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 3:
patients.push_back(new MaleIn());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
case 4:
patients.push_back(new MaleOut());
cout << patients.back() << endl;
patients[totalPatients]->enterPatientData();
totalPatients++;
break;
default:
return;
}
}
void Hospital::display(string type)
{
cout << "Patient Name Spouse Name Sex Patient Type Unit/Appt. Date Diagnosis" << endl;
cout << "===================================================================================" << endl;
if(type=="All")
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
else if(type=="Outpatient")
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
else
{
for(int i=0;i<patients.size();i++)
{
patients[i]->toString();
}
}
}
您可以使用 dynamic_cast
到某些 class 指针来检测给定实例是否属于 class:
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;
}
我认为这个问题可能与 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);
}