'Reference-Counting'에 해당되는 글 1건

  1. 2008.08.18 Reference-Counting

Reference-Counting

2008. 8. 18. 13:24 from 셈말짓기/C and C++

#include <windows.h>
#include <tchar.h>

#include <iostream>

/////////////////////////////////////////////////////////////////////////////
//
// Handle
//
/////////////////////////////////////////////////////////////////////////////
template<typename T>
class CRefCountedInstance
{
public:
 CRefCountedInstance ();

public:
 inline void AddRef       (void);
 inline void Release      (void);
 inline void Assign       (T *p);
 inline bool IsReferenced (void);
 inline T*   GetInstance  (void);

private:
 T   *Instance_;
 int  RefCount_;
};

template<typename T>
CRefCountedInstance<T>::CRefCountedInstance () :
 RefCount_ (0),
 Instance_ (0)
{
}

template<typename T>
void CRefCountedInstance<T>::AddRef (void)
{
 RefCount_++;
}

template<typename T>
void CRefCountedInstance<T>::Release (void)
{
 if (RefCount_>0)
 {
  RefCount_--;
 }

 if (RefCount_==0)
 {
  if (Instance_)
  {
   delete Instance_;
  }

  Instance_ = 0;
 }
}

template<typename T>
void CRefCountedInstance<T>::Assign (T *p)
{
 Instance_ = p;
 AddRef ();
}

template<typename T>
bool CRefCountedInstance<T>::IsReferenced (void)
{
 if (RefCount_==0)
  return false;

 return true;
}

template<typename T>
T* CRefCountedInstance<T>::GetInstance (void)
{
 return Instance_;
}

template<typename T>
class Handle
{
public:
 Handle ();
 explicit Handle (T *p);
 Handle (const Handle<T> &copy);
 ~Handle ();

public:
 Handle<T>& operator = (const Handle<T>& rhs);

public:
 inline T& operator*  () const;
 inline T* operator-> () const;
 inline T* Get    (void) const;

private:
 CRefCountedInstance<T>* Rep_;
};

template<typename T>
Handle<T>::Handle () : Rep_(0)
{
}

template<typename T>
Handle<T>::Handle (T *p)
{
 Rep_ = new CRefCountedInstance<T>();
 Rep_->Assign(p);
}

template<typename T>
Handle<T>::Handle (const Handle<T> &copy)
{
 Rep_ = copy.Rep_;

 if (Rep_)
  Rep_->AddRef ();
}

template<typename T>
Handle<T>::~Handle ()
{
 if (Rep_)
 {
  Rep_->Release ();

  if (!Rep_->IsReferenced())
   delete Rep_;
 }
}

template<typename T>
Handle<T>& Handle<T>::operator = (const Handle<T>& rhs)
{
 if (this == &rhs) return *this;

 if (Rep_)
  Rep_->Release ();

 Rep_ = rhs.Rep_;

 if (Rep_)
  Rep_->AddRef ();

 return *this;
}

template<typename T>
T& Handle<T>::operator*() const
{
 return *(Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::operator -> () const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}

template<typename T>
T* Handle<T>::Get (void) const
{
 if (Rep_==0)
  return 0;

 return (Rep_->GetInstance());
}


/////////////////////////////////////////////////////////////////////////////
//
// Application
//
/////////////////////////////////////////////////////////////////////////////
class Object
{
public:
 explicit Object(int n=0) : Data_(n)
 {
  std::cout << "Object(" << Data_ << ")" << std::endl;
 }

public:
 virtual ~Object()
 {
  std::cout << "~Object(" << Data_ << ")" << std::endl;
 }

public:
 int Data_;
};

Handle<Object> Test (Handle<Object> h)
{
 if (h.Get())
  h->Data_ = 3;

 return h;
}


/////////////////////////////////////////////////////////////////////////////
//
// Startup
//
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
 Handle<Object> p1( new Object(1) );
 Handle<Object> p2( new Object(2) );
 Handle<Object> p3;
 Handle<Object> p4;


 std::cout << std::endl;


 std::cout << "p2 = p1;" << std::endl;
 p2 = p1;
 std::cout << std::endl;


 std::cout << "p3 = p1;" << std::endl;
 p3 = p1;
 std::cout << std::endl;


 std::cout << "p4 = Test (p3);" << std::endl;
 p4 = Test (p3);

 std::cout << "p1->Data_ = " << p1->Data_ << std::endl;
 std::cout << "p2->Data_ = " << p2->Data_ << std::endl;
 std::cout << "p3->Data_ = " << p3->Data_ << std::endl;
 std::cout << "p4->Data_ = " << p3->Data_ << std::endl;

 return 0;
}
-----------------------------------------------------------------------------
Object(1)
Object(2)

p2 = p1;
~Object(2)

p3 = p1;

p4 = Test (p3);
p1->Data_ = 3
p2->Data_ = 3
p3->Data_ = 3
p4->Data_ = 3
~Object(3)

Posted by 셈말짓기 :