fork(1) download
  1. #include <iostream>
  2.  
  3. #define A_WITH_SHOWPATH
  4.  
  5.  
  6. #if 1 // helpers
  7. struct PainterPath { };
  8. class PathVisual
  9. {
  10. protected:
  11. PainterPath *mpPath;
  12. PathVisual(PainterPath *pPath) : mpPath(pPath) { }
  13. public:
  14. virtual void setVisible() = 0;
  15. PainterPath* Path() const { return mpPath; }
  16. };
  17. class PathGraphic : public PathVisual
  18. {
  19. public:
  20. PathGraphic(PainterPath *p) : PathVisual(p) { }
  21. virtual void setVisible() override { std::cout << "show graphic\n"; } // would display path graphic
  22. };
  23. class PathWidget : public PathVisual
  24. {
  25. public:
  26. PathWidget(PainterPath *p) : PathVisual(p) { }
  27. virtual void setVisible() override { std::cout << "show widget\n"; } // would display path widget
  28. };
  29. #endif // helpers
  30.  
  31.  
  32.  
  33. class A
  34. {
  35. #ifdef A_WITH_SHOWPATH
  36. private:
  37. std::string mPath;
  38. public:
  39. void setPath(std::string const &path) {
  40. mPath = path;
  41. std::cout << "path set to '" << mPath << "'\n";
  42. showPath();
  43. }
  44.  
  45. virtual void showPath() = 0; // to be called from outside, supposed to display mPath
  46. #endif
  47. };
  48.  
  49. class B : public A
  50. {
  51. protected:
  52. PainterPath *mpPath;
  53. B(PainterPath *pPath) : mpPath(pPath) { }
  54. public:
  55. virtual void showPath() = 0; // to be called from outside
  56. };
  57.  
  58. class C_g : public B {
  59. PathGraphic *mpGraphic;
  60. public:
  61. C_g(PathGraphic *pGraphic) : B(pGraphic->Path()), mpGraphic(pGraphic) { }
  62.  
  63. virtual void showPath() override {
  64. mpGraphic->setVisible();
  65. }
  66. };
  67.  
  68. class C_w : public B {
  69. PathWidget *mpWidget;
  70. public:
  71. C_w(PathWidget *pWidget) : B(pWidget->Path()), mpWidget(pWidget) { }
  72. virtual void showPath() override {
  73. mpWidget->setVisible();
  74. }
  75. };
  76.  
  77.  
  78. int main() {
  79. PainterPath p;
  80. PathGraphic pg(&p);
  81. PathWidget pw(&p);
  82. B* b_g = new C_g(&pg);
  83. B* b_w = new C_w(&pw);
  84.  
  85. std::cout << "Should say 'show graphic':\n";
  86. b_g->showPath();
  87. std::cout << "---------------------------\n";
  88. std::cout << "Should say 'show widget':\n";
  89. b_w->showPath();
  90. std::cout << "---------------------------\n";
  91.  
  92.  
  93. #ifdef A_WITH_SHOWPATH
  94. std::cout << "Should say \"path set to 'Test'\", but not 'show graphic':\n";
  95. b_g->setPath("Test");
  96. std::cout << "# Calling setPath(\"/root\") on a B pointer now also displays the PainterPath, which is not the intended behavior.\n";
  97. std::cout << "---------------------------\n";
  98. #endif
  99.  
  100.  
  101. return 0;
  102. }
  103.  
Success #stdin #stdout 0s 3460KB
stdin
Standard input is empty
stdout
Should say 'show graphic':
show graphic
---------------------------
Should say 'show widget':
show widget
---------------------------
Should say "path set to 'Test'", but not 'show graphic':
path set to 'Test'
show graphic
# Calling setPath("/root") on a B pointer now also displays the PainterPath, which is not the intended behavior.
---------------------------