fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. class ObutsuException
  5. {
  6. public:
  7. operator char* () const { return "MuriPo!"; }
  8. };
  9.  
  10. template <class T>
  11. class Obutsu
  12. {
  13. protected:
  14. T* pointer = NULL;
  15. public:
  16. Obutsu() {
  17. cout << "Hungry!" << endl;
  18. }
  19. Obutsu(T* t) : pointer(t) {
  20. if (pointer != NULL)
  21. cout << "Eat! (" << pointer << ')' << endl;
  22. else
  23. cout << "Hungry!" << endl;
  24. }
  25. ~Obutsu() {
  26. if (pointer != NULL)
  27. cout << "Poo! (" << pointer << ')' << endl;
  28. else
  29. cout << "Bye..." << endl;
  30. }
  31. void swap(Obutsu& obutsu) {
  32. T *tmp;
  33. tmp = pointer;
  34. pointer = obutsu.pointer;
  35. obutsu.pointer = tmp;
  36. }
  37. T* release() {
  38. T *t = pointer;
  39. pointer = NULL;
  40. return t;
  41. }
  42. T* get() const { return pointer; }
  43. operator bool () const { return (pointer != NULL); }
  44. Obutsu(const Obutsu& otbutsu) {
  45. throw ObutsuException();
  46. }
  47. Obutsu& operator = (const Obutsu& obutsu) const {
  48. throw ObutsuException();
  49. }
  50. };
  51.  
  52. template <class T>
  53. class Unko : public Obutsu<T>
  54. {
  55. public:
  56. Unko() {}
  57. Unko(T* t) : Obutsu<T>(t) {}
  58. ~Unko() { reset(NULL); }
  59. T& operator * () const {
  60. if (this->pointer == NULL) throw ObutsuException();
  61. return *(this->pointer);
  62. }
  63. T* operator -> () const { return this->pointer; }
  64. void reset(T* t = NULL) {
  65. if (this->pointer == t) return;
  66. if (this->pointer != NULL) delete this->pointer;
  67. this->pointer = t;
  68. }
  69. };
  70.  
  71. template <class T>
  72. class Unko<T[]> : public Obutsu<T>
  73. {
  74. public:
  75. Unko() {}
  76. Unko(T* t) : Obutsu<T>(t) {}
  77. ~Unko() { reset(NULL); }
  78. T& operator [] (int n) const {
  79. if (this->pointer == NULL) throw ObutsuException();
  80. return *(this->pointer + n);
  81. }
  82. void reset(T* t = NULL) {
  83. if (this->pointer == t) return;
  84. if (this->pointer != NULL) delete [] this->pointer;
  85. this->pointer = t;
  86. }
  87. };
  88.  
  89. class Value
  90. {
  91. private:
  92. int value;
  93. public:
  94. Value(int v) : value(v) {}
  95. ~Value() { cout << "Oh! God!" << endl; }
  96. int getValue() const { return value; }
  97. void setValue(int v) { value = v; }
  98. operator int () const { return value; }
  99. };
  100.  
  101. int main() {
  102. cout << "start" << endl;
  103. try {
  104. {
  105. Unko<double> unchi;
  106. cout << (bool)unchi << endl;
  107. cout << unchi.get() << endl;
  108. double *d = unchi.release();
  109. unchi.reset(new double);
  110. cout << (bool)unchi << endl;
  111. cout << unchi.get() << endl;
  112. if (d != NULL) delete d;
  113. }
  114. {
  115. Unko<float> ecchi(new float);
  116. cout << (bool)ecchi << endl;
  117. ecchi.reset();
  118. cout << (bool)ecchi << endl;
  119. }
  120. {
  121. Unko<int> unko(new int);
  122. Unko<int> poop(new int);
  123. *unko = 100;
  124. *poop = 200;
  125. // unko = poop; //MuriPo!
  126. unko.swap(poop);
  127. cout << "unko: " << *unko << endl;
  128. }
  129. {
  130. Unko<Value> val(new Value(777));
  131. cout << "value: " << val->getValue() << endl;
  132. val->setValue(999);
  133. cout << "value: " << *val << endl;
  134. }
  135. {
  136. Unko<int[]> arr(new int[10]);
  137. for (int i = 0 ; i < 10; i++) {
  138. arr[i] = i * i;
  139. cout << "arr[" << i << "] = " << arr[i] << endl;
  140. }
  141. }
  142. } catch (ObutsuException& ex) {
  143. cout << ex << endl;
  144. }
  145. cout << "finish" << endl;
  146. return 0;
  147. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
start
Hungry!
0
0
1
0x8fb1008
Bye...
Eat! (0x8fb1008)
1
0
Bye...
Eat! (0x8fb1008)
Eat! (0x8fb1018)
unko: 200
Bye...
Bye...
Eat! (0x8fb1018)
value: 777
value: 999
Oh! God!
Bye...
Eat! (0x8fb1028)
arr[0] = 0
arr[1] = 1
arr[2] = 4
arr[3] = 9
arr[4] = 16
arr[5] = 25
arr[6] = 36
arr[7] = 49
arr[8] = 64
arr[9] = 81
Bye...
finish