fork(1) download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template<class T, class Pref, class Suf> class Wrap;
  5. template<class T, class Suf>
  6. class Call_proxy {
  7. T* p;
  8. mutable bool own;
  9. Suf suffix;
  10. Call_proxy(T* pp, Suf su) :p(pp) , own(true) , suffix(su) { } // restrict creation
  11. Call_proxy& operator=(const Call_proxy&) ; // prevent assignment
  12. public:
  13. template<class U, class P, class S> friend class Wrap;
  14. Call_proxy(const Call_proxy& a) : p(a.p) , own(true) , suffix(a.suffix) { a.own=false; }
  15. ~Call_proxy() { if (own) suffix() ; }
  16.  
  17. T* operator->() const{ return p;}
  18. //T& operator->() const{ return *p;}
  19.  
  20. };
  21.  
  22.  
  23. template<class T, class Pref, class Suf>
  24. class Wrap {
  25. T* p;
  26. int* owned;
  27. void incr_owned() const{ if(owned) ++*owned; }
  28. void decr_owned() const{ if(owned && --*owned == 0) { delete p; delete owned; } }
  29. Pref prefix;
  30. Suf suffix;
  31. public:
  32. Wrap(T& x, Pref pr, Suf su) :p(&x) , owned(0) , prefix(pr) , suffix(su) { }
  33. Wrap(T* pp, Pref pr, Suf su) :p(pp) , owned(new int(1)) , prefix(pr) , suffix(su) { }
  34. Wrap(const Wrap& a)
  35. :p(a.p) , owned(a.owned) , prefix(a.prefix) , suffix(a.suffix) { incr_owned() ; }
  36. Wrap& operator=(const Wrap& a)
  37. {
  38. a.incr_owned() ;
  39. decr_owned() ;
  40. p = a.p;
  41. owned = a.owned;
  42. prefix= a.prefix;
  43. suffix= a.suffix;
  44. return *this;
  45. }
  46. ~Wrap() { decr_owned() ; }
  47. Call_proxy<T,Suf> operator->() const{ prefix() ; return Call_proxy<T,Suf>(p,suffix) ; }
  48. T* direct() const{ return p; } // extract pointer to wrapped object
  49. };
  50.  
  51. class X { // one user class
  52. public:
  53. X() { cout << " make an X\n"; }
  54. ~X() { cout << "destroy an X\n"; }
  55. int f() const{ cout << "f()"; return 1; }
  56. void g() const{ cout << "g()"; }
  57. };
  58. class Y { // another user class
  59. public:
  60. Y() { cout << " make a Y\n"; }
  61. ~Y() { cout << "destroy a Y\n"; }
  62. void h() const{ cout << "h()"; }
  63. };
  64.  
  65. void prefix() { cout << "prefix "; }
  66. void suffix() { cout << " suffix\n"; }
  67.  
  68. struct Pref { void operator()() const{ cout<< " Pref "; } };
  69. struct Suf { void operator()() const{ cout<< " Suf "; } };
  70.  
  71. template<class T>
  72. struct Shared : public Wrap<T,Pref, Suf>
  73. {
  74. Shared(T& obj) : Wrap<T,Pref, Suf>(obj,Pref() , Suf()) { }
  75. };
  76.  
  77. template<class T>
  78. struct Tracer : public Wrap<T,void(*)() ,void(*)()> {
  79. Tracer(T& x) : Wrap<T,void(*)() ,void(*)()>(x,::prefix,::suffix) { }
  80. };
  81.  
  82. int main() // test program
  83. {
  84. X x;
  85. Shared<X> xx(x) ;
  86. Tracer<Shared<X>> xxx(xx);
  87.  
  88. xx->g();
  89. xxx->g();
  90. return 0;
  91. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In function ‘int main()’:
prog.cpp:89:7: error: ‘struct Shared<X>’ has no member named ‘g’
  xxx->g();
       ^
stdout
Standard output is empty