#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> ©);
~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> ©)
{
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)