fork download
  1. //Smartpointer.h
  2. #ifndef SMARTPOINTER_H
  3. #define SMARTPOINTER_H
  4.  
  5. #include <map>
  6.  
  7. extern std::map<const void *, unsigned int> referencecounter;
  8.  
  9. template <class T> class Smartpointer{
  10. public:
  11. inline Smartpointer(){
  12. target = new T;
  13. referencecounter[target]++;
  14. }
  15. /*
  16. TODO: Fix constructors with a variadic template some day
  17. python code to generate constructors:
  18. s = ""
  19. for i in range(1, 11):
  20. s += "\ttemplate <"
  21. for j in range(1, i+1):
  22. s += "class A"+str(j)+", "
  23. s = s[:len(s) - 2]
  24. s += "> inline Smartpointer("
  25.  
  26. for j in range(1, i+1):
  27. s += "const A"+str(j)+" &a"+str(j)+", "
  28. s = s[:len(s) - 2]
  29. s += "){\n\t\ttarget = new T("
  30. for j in range(1, i+1):
  31. s += "a"+str(j)+", "
  32. s = s[:len(s) - 2]
  33. s += ");\n\t\treferencecounter[target]++;\n\t}\n"
  34. print s
  35. */
  36. template <class A1> inline Smartpointer(const A1 &a1){
  37. target = new T(a1);
  38. referencecounter[target]++;
  39. }
  40. template <class A1, class A2> inline Smartpointer(const A1 &a1, const A2 &a2){
  41. target = new T(a1, a2);
  42. referencecounter[target]++;
  43. }
  44. template <class A1, class A2, class A3> inline Smartpointer(const A1 &a1, const A2 &a2, const A3 &a3){
  45. target = new T(a1, a2, a3);
  46. referencecounter[target]++;
  47. }
  48. template <class A1, class A2, class A3, class A4> inline Smartpointer(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4){
  49. target = new T(a1, a2, a3, a4);
  50. referencecounter[target]++;
  51. }
  52. template <class A1, class A2, class A3, class A4, class A5> inline Smartpointer(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5){
  53. target = new T(a1, a2, a3, a4, a5);
  54. referencecounter[target]++;
  55. }
  56. template <class A1, class A2, class A3, class A4, class A5, class A6> inline Smartpointer(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6){
  57. target = new T(a1, a2, a3, a4, a5, a6);
  58. referencecounter[target]++;
  59. }
  60. template <class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline Smartpointer(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7){
  61. target = new T(a1, a2, a3, a4, a5, a6, a7);
  62. referencecounter[target]++;
  63. }
  64. template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline Smartpointer(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8){
  65. target = new T(a1, a2, a3, a4, a5, a6, a7, a8);
  66. referencecounter[target]++;
  67. }
  68. template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline Smartpointer(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9){
  69. target = new T(a1, a2, a3, a4, a5, a6, a7, a8, a9);
  70. referencecounter[target]++;
  71. }
  72. template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline Smartpointer(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10){
  73. target = new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
  74. referencecounter[target]++;
  75. }
  76.  
  77. inline Smartpointer(const Smartpointer &sp){
  78. target = sp.target;
  79. referencecounter[target]++;
  80. }
  81. template <class U> inline Smartpointer(Smartpointer<U> &sp){
  82. target = &(*sp);
  83. referencecounter[target]++;
  84. }
  85. inline Smartpointer<T> & operator = (const Smartpointer<T> &sp){
  86. if (target != sp.target){ //if they are equal nothing changes
  87. this->~Smartpointer(); //call the destructor to remove reference
  88. target = sp.target;
  89. referencecounter[target]++;
  90. }
  91. return *this;
  92. }
  93. inline bool operator < (const Smartpointer<T> &sp) const{
  94. return target < sp.target;
  95. }
  96. inline bool operator <= (const Smartpointer<T> &sp) const{
  97. return target <= sp.target;
  98. }
  99. inline bool operator > (const Smartpointer<T> &sp) const{
  100. return target > sp.target;
  101. }
  102. inline bool operator >= (const Smartpointer<T> &sp) const{
  103. return target >= sp.target;
  104. }
  105. inline bool operator == (const Smartpointer<T> &sp) const{
  106. return target == sp.target;
  107. }
  108. inline bool operator != (const Smartpointer<T> &sp) const{
  109. return target != sp.target;
  110. }
  111. inline T * operator -> (){
  112. return target;
  113. }
  114. inline const T * operator -> () const{
  115. return target;
  116. }
  117. inline T & operator * (){
  118. return *target;
  119. }
  120. inline const T & operator * () const{
  121. return *target;
  122. }
  123. inline ~Smartpointer(){
  124. if (referencecounter.count(target)){
  125. if (referencecounter[target] == 1){ //we are the last
  126. delete target;
  127. referencecounter.erase(target);
  128. }
  129. else //we are not the last
  130. referencecounter[target]--;
  131. }
  132. }
  133. static Smartpointer<T> adopt(T *t){
  134. Smartpointer<T> *st = static_cast<Smartpointer<T> *>(::operator new(sizeof st));
  135. st->target = t;
  136. Smartpointer<T> lst(*st);
  137. ::operator delete(st);
  138. return lst;
  139. }
  140. private:
  141. T *target;
  142. };
  143.  
  144. //template <class T> std::map<const T *, unsigned int> Smartpointer<T>::referencecounter;
  145.  
  146. #endif //SMARTPOINTER_H
  147.  
  148.  
  149. //Smartpointer.cpp
  150. //#include "smartpointer.h"
  151. std::map<const void *, unsigned int> referencecounter;
  152.  
  153. //main.cpp
  154. //#include "smartpointer.h"
  155. #include <iostream>
  156.  
  157. class DifficultClass{
  158. public:
  159. DifficultClass(int i, double d){
  160. this->count = ++counter;
  161. std::cout << "created DCO " << count << '\n';
  162. }
  163. ~DifficultClass(){
  164. std::cout << "destroyed DCO " << count << '\n';
  165. }
  166. private:
  167. DifficultClass(const DifficultClass &dc);
  168. static int counter;
  169. int count;
  170. };
  171. int DifficultClass::counter;
  172.  
  173. class DerivedClass : public DifficultClass{
  174. public:
  175. DerivedClass(const char *p) : DifficultClass(42, 17.){
  176. }
  177. };
  178.  
  179. int main(){
  180. std::cout << "\nLine " << __LINE__ << " Simple scope --------------------------\n";
  181. {
  182. Smartpointer<DifficultClass> dcsp(42, 17.);
  183. }
  184. std::cout << "\nLine " << __LINE__ << " Copies and scope -------------------------------\n";
  185. {
  186. Smartpointer<DifficultClass> dcsp(42, 17.);
  187. Smartpointer<DifficultClass> dcsp2(dcsp);
  188. {
  189. Smartpointer<DifficultClass> dcsp3(dcsp);
  190. Smartpointer<DifficultClass> dcsp4(dcsp3);
  191. }
  192. Smartpointer<DifficultClass> dcsp3(dcsp);
  193. }
  194. std::cout << "\nLine " << __LINE__ << " assignment -------------------------------\n";
  195. {
  196. Smartpointer<DifficultClass> dcsp1(42, 17.);
  197. Smartpointer<DifficultClass> dcsp2(17, 42.);
  198. {
  199. dcsp1 = dcsp2;
  200. }
  201. }
  202. std::cout << "\nLine " << __LINE__ << " derived class with downcast -------------------------------\n";
  203. {
  204. Smartpointer<DerivedClass> dcsp("hello");
  205. {
  206. Smartpointer<DifficultClass> dcsp2(dcsp); //automatic downcast
  207. }
  208. }
  209. std::cout << "\nLine " << __LINE__ << " adopting pointers -------------------------------\n";
  210. {
  211. DifficultClass *dc = new DifficultClass(42, 7.);
  212. Smartpointer<DifficultClass> dcsp = Smartpointer<DifficultClass>::adopt(dc);
  213. Smartpointer<DifficultClass> dcsp2 = Smartpointer<DifficultClass>::adopt(dc);
  214. Smartpointer<DifficultClass> dcsp3 = Smartpointer<DifficultClass>::adopt(dc);
  215. }
  216. }
  217.  
Success #stdin #stdout 0.01s 2820KB
stdin
Standard input is empty
stdout
Line 180 Simple scope --------------------------
created DCO 1
destroyed DCO 1

Line 184 Copies and scope -------------------------------
created DCO 2
destroyed DCO 2

Line 194 assignment -------------------------------
created DCO 3
created DCO 4
destroyed DCO 3
destroyed DCO 4

Line 202 derived class with downcast -------------------------------
created DCO 5
destroyed DCO 5

Line 209 adopting pointers -------------------------------
created DCO 6
destroyed DCO 6