智能指针3


#include <iostream>
#include <stdexcept>
using namespace std;

 


#define TEST_SMARTPTR
class Stub
{
public:
 void print() {
 // iRef = 1;
  cout<<"Stub: print"<< iRef <<endl;
 }
 Stub() {iRef = 1;};
 ~Stub(){
  cout<<"Stub: Destructor"<<endl;
 }
public:
 void AddReference(){iRef++;};
 int RemoveReference(){ iRef--; return iRef;};
private:
 int iRef;

};
class Sentry
{
public:
 Sentry(int lock){ lock_ = lock;}
 ~Sentry(){}
private:
 int lock_;
};

template <class T>
class RefCountingTraits
{
public:
  void Refer(T* p)
 {
  Sentry s(lock_);
  if( NULL != p )
   p->AddReference();
 }
  void Unrefer(T* p)
 {
  Sentry s(lock_);
  if ( p != NULL )
   if(p->RemoveReference() == 0 )
    delete p;
 }
private:
 int lock_;
};

template <class T,class RCTraits = RefCountingTraits<T> >
class SmartPtr :private RCTraits
{
public:
 SmartPtr(T *p = 0): ptr(p) { }
 SmartPtr(const SmartPtr& src): ptr(src.ptr) {
  RCTraits::Refer(ptr);
 }
 SmartPtr& operator= (const SmartPtr& rhs) {
  // self-assigning is also right
  //++*rhs.pUse;
  RCTraits::Refer(rhs.ptr);
  decrUse();
  ptr = rhs.ptr;

  return *this;
 }
 T *operator->() {
  if (ptr)
  return ptr;
  throw std::runtime_error("access through NULL pointer");
 }
 const T *operator->() const {
  if (ptr)
   return ptr;
  throw std::runtime_error("access through NULL pointer");
 }
 T &operator*() {
  if (ptr)
   return *ptr;
  throw std::runtime_error("dereference of NULL pointer");
 }
 const T &operator*() const {
  if (ptr)
   return *ptr;
  throw std::runtime_error("dereference of NULL pointer");
 }
 ~SmartPtr() {
  decrUse();
 #ifdef TEST_SMARTPTR
  std::cout<<"SmartPtr: Destructor"<<std::endl;// for testing
 #endif
 }
private:
 void decrUse() {
  RCTraits::Unrefer(ptr);
 }
 T *ptr;
};

int main()
{
 try {
  SmartPtr<Stub> t;
  t->print();
 } catch (const exception& err) {
  cout<<err.what()<<endl;
 }
 SmartPtr<Stub> t1(new Stub);
 SmartPtr<Stub> t2(t1);
 SmartPtr<Stub> t3(new Stub);
 t3 = t2;
 t1->print();
 (*t3).print();
 getchar();
 return 0;
}

你可能感兴趣的:(智能指针3)