fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <functional>
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7.  
  8. //folgendes wäre Teil der Standardlibrary
  9. //nur minimale features implementiert (zeitgründe)
  10. class Integer {
  11. public:
  12. typedef int BaseType;
  13. int value;
  14.  
  15. Integer(int value=0) : value(value) {}
  16. Integer(Integer const& other) : value(other.value) {}
  17.  
  18. Integer& operator=(Integer const& other) {
  19. value=other.value;
  20. return *this;
  21. }
  22. };
  23.  
  24. Integer operator+(Integer const& lhs, Integer const& rhs) {
  25. return Integer(lhs.value+rhs.value);
  26. }
  27.  
  28. class PositiveInteger : protected Integer {
  29. public:
  30. typedef int BaseType;
  31.  
  32. PositiveInteger(int value=0) : Integer(value) { if(value<0) throw "Negative Value"; }
  33. PositiveInteger(Integer const& other) : Integer(other) { if(value<0) throw "Negative Value"; }
  34.  
  35. PositiveInteger& operator=(Integer const& other) {
  36. if(other.value < 0) throw "Negative Value";
  37. value=other.value;
  38. return *this;
  39. }
  40.  
  41. operator Integer() { return *this; }
  42. };
  43.  
  44.  
  45.  
  46. template<typename T>
  47. class Vector {
  48. private:
  49. vector<T> impl;
  50.  
  51. public:
  52. void add(T const& val) {
  53. impl.push_back(val);
  54. }
  55.  
  56. template<typename F>
  57. void for_each(F f) {
  58. for(auto& obj : impl) {
  59. f(obj);
  60. }
  61. }
  62. };
  63.  
  64. template<typename T>
  65. class ChangeObserver : public Vector<function<void(T const&, T const&)> > {
  66. public:
  67. void change(T const& oldVal, T const& newVal) {
  68. this->for_each([&](function<void(T const&, T const&)> f) { f(oldVal, newVal); });
  69. }
  70. };
  71.  
  72. template<typename ValueType>
  73. class ChangeObservableArithmeticType : private ValueType, public ChangeObserver<ValueType> {
  74. public:
  75. typedef typename ValueType::BaseType BaseType;
  76. ChangeObservableArithmeticType(typename ValueType::BaseType value=0) : ValueType(value) {}
  77. ChangeObservableArithmeticType(ChangeObservableArithmeticType const& other) : ValueType(other) {}
  78. ChangeObservableArithmeticType(ValueType const& other) : ValueType(other) {}
  79.  
  80. ChangeObservableArithmeticType& operator=(ChangeObservableArithmeticType const& other) {
  81. this->change(*this, other);
  82. this->value=other.value;
  83. return *this;
  84. }
  85.  
  86. operator ValueType() {
  87. return *this;
  88. }
  89. };
  90.  
  91. class Radius : public ChangeObservableArithmeticType<PositiveInteger> {
  92. };
  93.  
  94. class Kreis : public Radius {
  95. public:
  96. Kreis() {
  97. add([&](::PositiveInteger const&, ::PositiveInteger const&) {
  98. redraw();
  99. });
  100.  
  101. redraw();
  102. }
  103.  
  104. void redraw() {
  105. cout<<"Radius changed, Kreis redrawn\n";
  106. }
  107. };
  108.  
  109. int main() {
  110. //2x redraw ausführen:
  111. Kreis k;
  112. k.ChangeObservableArithmeticType::operator=(7);
  113.  
  114. try {
  115. k.ChangeObservableArithmeticType::operator=(-7);
  116. } catch(...) {
  117. cout<<"Error\n";
  118. }
  119.  
  120. return 0;
  121. }
  122.  
  123.  
Success #stdin #stdout 0s 2988KB
stdin
Standard input is empty
stdout
Radius changed, Kreis redrawn
Radius changed, Kreis redrawn
Error