fork(1) download
  1. #include <iostream>
  2. #include <memory>
  3. #include <map>
  4.  
  5. using namespace std;
  6.  
  7. class NullPtr_t
  8. {
  9. public:
  10. NullPtr_t() : zero(NULL) {}
  11. template< class T >
  12. operator T* () const { return NULL; }
  13. template< class T, class C >
  14. operator T C::* () const { return NULL; }
  15. private:
  16. void operator &() const;
  17. void *zero;
  18. };
  19.  
  20. inline NullPtr_t getNullPtr() { return NullPtr_t(); }
  21. #define nullptr getNullPtr()
  22.  
  23.  
  24. template< class T, class A = allocator< T > >
  25. class FooPtr
  26. {
  27. typedef T FOO, *LPFOO;
  28. typedef A ALLO;
  29. typedef map< LPFOO, int > REFMAP, *LPREFMAP;
  30.  
  31. public:
  32.  
  33. FooPtr() : _ptr(nullptr) {
  34. }
  35.  
  36. FooPtr(LPFOO ptr) : _ptr(ptr) {
  37. if (_ptr == nullptr) {
  38. return;
  39. }
  40. REFMAP& m = refmap();
  41. m[_ptr]++;
  42. }
  43.  
  44. FooPtr(const FooPtr& other) : _ptr(other._ptr) {
  45. if (_ptr == nullptr) {
  46. return;
  47. }
  48. REFMAP& m = refmap();
  49. if (m[_ptr] == 0) {
  50. _ptr = nullptr;
  51. return;
  52. // or throw Exception
  53. }
  54. m[_ptr]++;
  55. }
  56.  
  57. ~FooPtr() {
  58. if (_ptr == nullptr) {
  59. return;
  60. }
  61. REFMAP& m = refmap();
  62. m[_ptr]--;
  63. if (m[_ptr] == 0) {
  64. ALLO allo;
  65. allo.destroy(_ptr);
  66. allo.deallocate(_ptr, 1);
  67. }
  68. _ptr = nullptr;
  69. }
  70.  
  71. FOO& operator *() {
  72. return *_ptr;
  73. }
  74.  
  75. FooPtr& operator = (const FooPtr& other) {
  76. clear();
  77. _ptr = other._ptr;
  78. if (_ptr != nullptr) {
  79. REFMAP& m = refmap();
  80. if (m[_ptr] == 0) {
  81. _ptr = nullptr;
  82. // or throw Exception
  83. } else {
  84. m[_ptr]++;
  85. }
  86. }
  87. return *this;
  88. }
  89.  
  90. FooPtr& operator = (const LPFOO foo) {
  91. clear();
  92. if (foo == nullptr) {
  93. return *this;
  94. }
  95.  
  96. // ALLO allo;
  97. // _ptr = allo.allocate(1);
  98. // allo.construct(_ptr, *foo);
  99. _ptr = foo;
  100.  
  101. REFMAP& m = refmap();
  102. m[_ptr]++;
  103. return *this;
  104. }
  105.  
  106. /*
  107. FooPtr& operator = (const NullPtr_t&) {
  108. clear();
  109. return *this;
  110. }
  111. */
  112.  
  113. void clear() {
  114. if (_ptr == nullptr) {
  115. return;
  116. }
  117. REFMAP& m = refmap();
  118. m[_ptr]--;
  119. if (m[_ptr] == 0) {
  120. ALLO allo;
  121. allo.destroy(_ptr);
  122. allo.deallocate(_ptr, 1);
  123. }
  124. _ptr = nullptr;
  125. }
  126.  
  127. LPFOO operator -> () {
  128. return _ptr;
  129. }
  130.  
  131. private:
  132. LPFOO _ptr;
  133.  
  134.  
  135. REFMAP& refmap() {
  136. static REFMAP ref;
  137. return ref;
  138. }
  139. };
  140.  
  141.  
  142. class Hoge
  143. {
  144. public:
  145. Hoge() : id(counter()) {
  146. cout << "Hoge() : " << id << endl;
  147. }
  148. Hoge(const Hoge&) : id(counter()) {
  149. cout << "Hoge(Hoge&) : " << id << endl;
  150. }
  151.  
  152. ~Hoge() {
  153. cout << "~Hoge() : " << id << endl;
  154. }
  155.  
  156. operator int () {
  157. return id;
  158. }
  159.  
  160. void print() {
  161. cout << "Hoge method: " << id << endl;
  162. }
  163.  
  164. private:
  165. const int id;
  166. static int counter() {
  167. static int c = 0;
  168. return ++c;
  169. }
  170. };
  171.  
  172. FooPtr<Hoge> getHoge() {
  173. FooPtr<Hoge> temp(new Hoge);
  174. return temp;
  175. }
  176.  
  177.  
  178. int main() {
  179. // your code goes here
  180. cout << "** begin of program **" << endl;
  181.  
  182. FooPtr<Hoge> hoge1(new Hoge);
  183.  
  184. {
  185. cout << "-- test 1 --" << endl;
  186. FooPtr<Hoge> empty;
  187.  
  188. empty = hoge1;
  189.  
  190. cout << "hoge1: " << *hoge1 << endl;
  191. cout << "empty: " << *empty << endl;
  192. }
  193.  
  194. {
  195. cout << "-- test 2 --" << endl;
  196. FooPtr<Hoge> hoge2(hoge1);
  197.  
  198. cout << "hoge1: " << *hoge1 << endl;
  199. cout << "hoge2: " << *hoge2 << endl;
  200. }
  201.  
  202. {
  203. cout << "-- test 3 --" << endl;
  204. FooPtr<Hoge> hoge3 = hoge1;
  205.  
  206. cout << "hoge1: " << *hoge1 << endl;
  207. cout << "hgoe3: " << *hoge3 << endl;
  208. }
  209.  
  210. {
  211. cout << "-- test 4 --" << endl;
  212. FooPtr<Hoge> hoge4 = hoge1;
  213. hoge1 = nullptr;
  214.  
  215. cout << "hoge4: " << *hoge4 << endl;
  216. }
  217.  
  218. {
  219. cout << "-- test 5 --" << endl;
  220. hoge1 = new Hoge;
  221.  
  222. cout << "hoge1: " << *hoge1 << endl;
  223. }
  224.  
  225. {
  226. cout << "-- test 6 --" << endl;
  227.  
  228. hoge1->print();
  229. }
  230.  
  231. {
  232. cout << "-- test 7 --" << endl;
  233.  
  234. getHoge();
  235.  
  236. hoge1 = getHoge();
  237. }
  238.  
  239. cout << "** end of program **" << endl;
  240. return 0;
  241. }
Success #stdin #stdout 0s 3480KB
stdin
Standard input is empty
stdout
** begin of program **
Hoge() : 1
-- test 1 --
hoge1: 1
empty: 1
-- test 2 --
hoge1: 1
hoge2: 1
-- test 3 --
hoge1: 1
hgoe3: 1
-- test 4 --
hoge4: 1
~Hoge() : 1
-- test 5 --
Hoge() : 2
hoge1: 2
-- test 6 --
Hoge method: 2
-- test 7 --
Hoge() : 3
~Hoge() : 3
Hoge() : 4
~Hoge() : 2
** end of program **
~Hoge() : 4