访问者模式.cpp
#include <iostream>
#include <list>
#include <memory>
using namespace std;
namespace ns1
{class Medicine {public:virtual ~Medicine() {}virtual string getMdcName() const = 0; virtual float getPrice() const = 0; };class M_asplcrp : public Medicine {public:string getMdcName() const override{return "Aspirin enteric-coated tablets";}float getPrice() const override{return 46.8f; }};class M_fftdnhsp : public Medicine {public:string getMdcName() const override{return "Fluvastatin sodium sustained-release tablets";}float getPrice() const override{return 111.3f; }};class M_dlx : public Medicine {public:string getMdcName() const override{return "Deanxit";}float getPrice() const override{return 122.0f; }};class MedicineProc {list<shared_ptr<Medicine>> m_mdclist; public:void addMedicine(const shared_ptr<Medicine> &p_mdc) { m_mdclist.push_back(p_mdc); }void procAction(const string &strvisitor) {if (strvisitor == "Toll collector") {float totalcost = 0.0f; for (auto iter = m_mdclist.begin(); iter != m_mdclist.end(); ++iter){float tmpprice = (*iter)->getPrice();totalcost += tmpprice;cout << "yao: " << (*iter)->getMdcName() << ", price: " << tmpprice << endl;}cout << "total price: " << totalcost << ", Toll collector charges a fee!" << endl;}else if (strvisitor == "Drug taking personnel") for (auto iter = m_mdclist.begin(); iter != m_mdclist.end(); ++iter)cout << "Drug taking personnel give " << (*iter)->getMdcName() << " to me!" << endl;else if (strvisitor == "dietitian")cout << "Nutritionist suggested: match coarse grains with staple foods and eat meat properly!" << endl;else if (strvisitor == "Fitness coach")cout << "The fitness coach suggested: do more aerobic exercises such as jogging (35 minutes), warm up before and after jogging, avoid anxiety, avoid staying up late, and take a bed rest before 22:30!" << endl;}};
}namespace ns2
{class Visitor; class Medicine {public:virtual ~Medicine() {}virtual void Accept(shared_ptr<Visitor> &pvisitor) = 0; public:virtual string getMdcName() = 0; virtual float getPrice() = 0; };class M_asplcrp : public Medicine {public:string getMdcName() override { return "Aspirin enteric-coated tablets"; }float getPrice() override { return 46.8f; }public:void Accept(shared_ptr<Visitor> &pvisitor) override;};class M_fftdnhsp : public Medicine {public:string getMdcName() override { return "Fluvastatin sodium sustained-release tablets"; }float getPrice() override { return 111.3f; }public:void Accept(shared_ptr<Visitor> &pvisitor) override;};class M_dlx : public Medicine {public:string getMdcName() override { return "Deanxit"; }float getPrice() override { return 122.0f; }public:void Accept(shared_ptr<Visitor> &pvisitor) override;};class Visitor {public:virtual ~Visitor() {}virtual void Visit_elm_asplcrp(M_asplcrp *pelem) = 0; virtual void Visit_elm_fftdnhsp(M_fftdnhsp *pelem) = 0; virtual void Visit_elm_dlx(M_dlx *pelem) = 0; };class Visitor_SFRY : public Visitor {float m_totalcost = 0.0f; public:void Visit_elm_asplcrp(M_asplcrp *pelem) override{float tmpprice = pelem->getPrice();cout << "yao: " << pelem->getMdcName() << ", price: " << tmpprice << endl;m_totalcost += tmpprice;}void Visit_elm_fftdnhsp(M_fftdnhsp *pelem) override{float tmpprice = pelem->getPrice();cout << "yao: " << pelem->getMdcName() << ", price: " << tmpprice << endl;m_totalcost += tmpprice;}void Visit_elm_dlx(M_dlx *pelem) override{float tmpprice = pelem->getPrice();cout << "yao: " << pelem->getMdcName() << ", price: " << tmpprice << endl;m_totalcost += tmpprice;}float getTotalCost() const { return m_totalcost; }};class Visitor_QYRY : public Visitor {public:void Visit_elm_asplcrp(M_asplcrp *pelem) override{cout << "Drug taking personnel give " << pelem->getMdcName() << " to me!" << endl;}void Visit_elm_fftdnhsp(M_fftdnhsp *pelem) override{cout << "Drug taking personnel give " << pelem->getMdcName() << " to me!" << endl;}void Visit_elm_dlx(M_dlx *pelem) override{cout << "Drug taking personnel give " << pelem->getMdcName() << " to me!" << endl;}};class Visitor_YYS : public Visitor {public:void Visit_elm_asplcrp(M_asplcrp *pelem) override{cout << "The nutritionist suggested: Eating more coarse grains and less oil can effectively prevent blood clots!" << endl;}void Visit_elm_fftdnhsp(M_fftdnhsp *pelem) override{cout << "The nutritionist suggested: Eating more mushrooms, onions, and kiwifruit can effectively reduce blood lipids!" << endl;}void Visit_elm_dlx(M_dlx *pelem) override{cout << "The nutritionist suggested: Go out more to breathe fresh air, get more sunshine, go to more crowded places, and keep an optimistic and cheerful mood!" << endl;}};void M_asplcrp::Accept(shared_ptr<Visitor> &pvisitor){pvisitor->Visit_elm_asplcrp(this);}void M_fftdnhsp::Accept(shared_ptr<Visitor> &pvisitor){pvisitor->Visit_elm_fftdnhsp(this);}void M_dlx::Accept(shared_ptr<Visitor> &pvisitor){pvisitor->Visit_elm_dlx(this);}class ObjectStructure {list<shared_ptr<Medicine>> m_mdclist; public:void addMedicine(const shared_ptr<Medicine> &p_mdc){m_mdclist.push_back(p_mdc);}void procAction(shared_ptr<Visitor> &pvisitor){for (auto iter = m_mdclist.begin(); iter != m_mdclist.end(); ++iter)(*iter)->Accept(pvisitor);}};
}namespace ns3
{class Medicine; class Visitor {public:virtual ~Visitor() {}virtual void Visit(Medicine *const pelem) = 0;};class Medicine {public:virtual ~Medicine() {}virtual void Accept(shared_ptr<Visitor> &pvisitor) { pvisitor->Visit(this); }public:virtual string getMdcName() const = 0; virtual float getPrice() const = 0; };class M_asplcrp : public Medicine {public:string getMdcName() const override { return "Aspirin enteric-coated tablets"; }float getPrice() const override { return 46.8f; }};class M_fftdnhsp : public Medicine {public:string getMdcName() const override { return "Fluvastatin sodium sustained-release tablets"; }float getPrice() const override { return 111.3f; }};class M_dlx : public Medicine {public:string getMdcName() const override { return "Deanxit"; }float getPrice() const override { return 122.0f; }};class Visitor_SFRY : public Visitor {float m_totalcost = 0.0f; public:void Visit(Medicine *const m) override{float tmpprice = m->getPrice();m_totalcost += tmpprice;cout << "yao: " << m->getMdcName() << ", price: " << tmpprice << endl;}float getTotalCost() const { return m_totalcost; } };class Visitor_QYRY : public Visitor {public:void Visit(Medicine *const m) override{cout << "Drug taking personnel give " << m->getMdcName() << " to me!" << endl;}};class Visitor_YYS : public Visitor {public:void Visit(Medicine *const m) override{cout << "The nutritionist suggested: Eating more coarse grains and less oil can effectively prevent blood clots!" << endl;cout << "The nutritionist suggested: Eating more mushrooms, onions, and kiwifruit can effectively reduce blood lipids!" << endl;cout << "The nutritionist suggested: Go out more to breathe fresh air, get more sunshine, go to more crowded places, and keep an optimistic and cheerful mood!" << endl;}};class ObjectStructure {list<shared_ptr<Medicine>> m_mdclist; public:void addMedicine(const shared_ptr<Medicine> &p_mdc){m_mdclist.push_back(p_mdc);}void procAction(shared_ptr<Visitor> &pvisitor){for (auto iter = m_mdclist.begin(); iter != m_mdclist.end(); ++iter)(*iter)->Accept(pvisitor);}};
}int main()
{
#if 0using namespace ns1;shared_ptr<Medicine> pm1(new M_asplcrp()); shared_ptr<Medicine> pm2(new M_fftdnhsp()); shared_ptr<Medicine> pm3(new M_dlx()); MedicineProc mdcprocobj;mdcprocobj.addMedicine(pm1);mdcprocobj.addMedicine(pm2);mdcprocobj.addMedicine(pm3);mdcprocobj.procAction("Toll collector");mdcprocobj.procAction("Drug taking personnel");
#endif#if 1using namespace ns3;shared_ptr<Medicine> mdc_asplcrp(new M_asplcrp());shared_ptr<Medicine> mdc_fftdnhsp(new M_fftdnhsp());shared_ptr<Medicine> mdc_dlx(new M_dlx());shared_ptr<Visitor> visitor_sf(new Visitor_SFRY()); mdc_asplcrp->Accept(visitor_sf); mdc_fftdnhsp->Accept(visitor_sf); mdc_dlx->Accept(visitor_sf); cout << "total price: " << dynamic_pointer_cast<Visitor_SFRY>(visitor_sf)->getTotalCost() << ", the toll collector charged me!" << endl;shared_ptr<Visitor> visitor_qy(new Visitor_QYRY()); mdc_asplcrp->Accept(visitor_qy); mdc_fftdnhsp->Accept(visitor_qy); mdc_dlx->Accept(visitor_qy); shared_ptr<Visitor> visitor_yys(new Visitor_YYS()); mdc_asplcrp->Accept(visitor_yys); mdc_fftdnhsp->Accept(visitor_yys); mdc_dlx->Accept(visitor_yys); shared_ptr<ObjectStructure> objstruc(new ObjectStructure());objstruc->addMedicine(mdc_asplcrp);objstruc->addMedicine(mdc_fftdnhsp);objstruc->addMedicine(mdc_dlx);objstruc->procAction(visitor_yys);
#endifcout << "Over!\n";return 0;
}