fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <memory>
  4.  
  5. struct PBaseVisitor;
  6.  
  7. struct PBase {
  8. virtual int get_id() { return 0; }
  9. virtual void accept(PBaseVisitor &v);
  10. };
  11. struct P1 : PBase {
  12. int get_id() override { return 1; }
  13. void accept(PBaseVisitor &v) override;
  14. };
  15. struct P2 : PBase {
  16. int get_id() override { return 2; }
  17. void accept(PBaseVisitor &v) override;
  18. };
  19.  
  20. class SBase {
  21. public:
  22. virtual ~SBase() {}
  23. void doIt(PBase &p) { this->internalDoIt(p); }
  24.  
  25. private:
  26. virtual void internalDoIt(PBase &p) = 0;
  27. };
  28.  
  29. struct PBaseVisitor {
  30. virtual ~PBaseVisitor() {}
  31. virtual void visit(PBase &p) = 0;
  32. virtual void visit(P1 &p) { visit(static_cast<PBase &>(p)); };
  33. virtual void visit(P2 &p) { visit(static_cast<PBase &>(p)); };
  34. };
  35.  
  36. void PBase::accept(PBaseVisitor &v) { v.visit(*this); }
  37. void P1::accept(PBaseVisitor &v) { v.visit(*this); }
  38. void P2::accept(PBaseVisitor &v) { v.visit(*this); }
  39.  
  40. class S : public SBase {
  41. struct doItImpl : PBaseVisitor {
  42. doItImpl(S *s) : s(s) {}
  43. S *s;
  44. virtual void visit(PBase &p) { s->internalDoItImpl(p); };
  45. void visit(P1 &p) override { s->internalDoItImpl(p); };
  46. void visit(P2 &p) override { s->internalDoItImpl(p); };
  47. };
  48. virtual void internalDoIt(PBase &p) {
  49. doItImpl impl(this);
  50. p.accept(impl);
  51. }
  52. void internalDoItImpl(PBase &p) { std::cout << "PBase: " << p.get_id() << '\n'; }
  53. void internalDoItImpl(P1 &p) { std::cout << "P1: " << p.get_id() << '\n'; }
  54. void internalDoItImpl(P2 &p) { std::cout << "P2: " << p.get_id() << '\n'; }
  55. };
  56.  
  57. int main() {
  58. std::vector<std::unique_ptr<PBase> > vec;
  59. vec.emplace_back(new PBase);
  60. vec.emplace_back(new P1);
  61. vec.emplace_back(new P2);
  62.  
  63. S s;
  64. SBase &bref = s; // Angenommn, dass du von irgendwo her einen
  65. // Basisklassen-Zeiger/Referenz hast..
  66.  
  67. for (auto &p : vec)
  68. bref.doIt(*p);
  69. }
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
PBase: 0
P1: 1
P2: 2