說明:相關(guān)技術(shù)參考自:http://www.cublog.cn/u/18517/showart_241240.html
上面這個,寫的真的很不錯,通俗易懂。推薦大家去看下。下面是看完上面的文章后,自己嘗試的:
//調(diào)用
上面這個,寫的真的很不錯,通俗易懂。推薦大家去看下。下面是看完上面的文章后,自己嘗試的:
//智能指針聲明及實(shí)現(xiàn)
/************************************************************************/
/** 智能指針聲明
/************************************************************************/
#pragma once
#include <iostream>
#include <stdexcept>
using namespace std;
#ifndef TEST_SMARTPTR
#define TEST_SMARTPTR
#endif
template < class T >
class TSmartPtr
{
public:
//默認(rèn)構(gòu)造函數(shù)
TSmartPtr(T* pTObject = NULL) : m_pTObject(pTObject), m_pCount(new int(1)) {}
//拷貝構(gòu)造函數(shù)
TSmartPtr(const TSmartPtr& src) : m_pTObject(src.m_pTObject), m_pCount(src.m_pCount) { ++(*m_pCount); }
//析構(gòu)函數(shù)
virtual ~TSmartPtr()
{
#ifdef TEST_SMARTPTR
cout << "SmartPtr Object Free." << endl;
#endif
DoDecUseCount();
}
//=重載
TSmartPtr& operator = (const TSmartPtr& rhs)
{
// self-assigning is also right
++*rhs.m_pCount; //源智能指針的引用計數(shù)增1
DoDecUseCount(); //目標(biāo)智能指針的引用計數(shù)減1。此非常有必要。因為該指針既然要指向rhs,
//則說明它就不再想去管理自身原本的指針對象了。因此需要減1()
//在自身引用計數(shù)減1后,有可能自身原本維護(hù)的指針對象會被釋放掉,也有可能不會。
//(因為,先前所管理的對象,有可能還有其他的智能指針對象在維護(hù)著了。)
//因此,上面這兩句才是精髓。
m_pTObject = rhs.m_pTObject;
m_pCount = rhs.m_pCount;
return *this;
}
//->重載
T* operator -> ()
{
if (NULL != m_pTObject)
return m_pTObject;
throw runtime_error("access through NULL pointer");
}
const T* operator -> () const
{
if (NULL != m_pTObject)
return m_pTObject;
throw runtime_error("access through NULL pointr");
}
//*重載
T& operator * ()
{
if (NULL != m_pTObject)
return *m_pTObject;
throw runtime_error("dereference of NULL pointer");
}
const T& operator * () const
{
if (NULL != m_pTObject)
return &m_pTObject;
throw runtime_error("dereference of NULL pointer");
}
private:
//引用計數(shù)減1
void DoDecUseCount(void)
{
if (0 == --*m_pCount)
{
if (NULL != m_pTObject)
{
delete m_pTObject;
m_pTObject = NULL;
}
delete m_pCount;
m_pCount = NULL;
}
}
T* m_pTObject;
int* m_pCount;
}
/************************************************************************/
/** 智能指針聲明
/************************************************************************/
#pragma once
#include <iostream>
#include <stdexcept>
using namespace std;
#ifndef TEST_SMARTPTR
#define TEST_SMARTPTR
#endif
template < class T >
class TSmartPtr
{
public:
//默認(rèn)構(gòu)造函數(shù)
TSmartPtr(T* pTObject = NULL) : m_pTObject(pTObject), m_pCount(new int(1)) {}
//拷貝構(gòu)造函數(shù)
TSmartPtr(const TSmartPtr& src) : m_pTObject(src.m_pTObject), m_pCount(src.m_pCount) { ++(*m_pCount); }
//析構(gòu)函數(shù)
virtual ~TSmartPtr()
{
#ifdef TEST_SMARTPTR
cout << "SmartPtr Object Free." << endl;
#endif
DoDecUseCount();
}
//=重載
TSmartPtr& operator = (const TSmartPtr& rhs)
{
// self-assigning is also right
++*rhs.m_pCount; //源智能指針的引用計數(shù)增1
DoDecUseCount(); //目標(biāo)智能指針的引用計數(shù)減1。此非常有必要。因為該指針既然要指向rhs,
//則說明它就不再想去管理自身原本的指針對象了。因此需要減1()
//在自身引用計數(shù)減1后,有可能自身原本維護(hù)的指針對象會被釋放掉,也有可能不會。
//(因為,先前所管理的對象,有可能還有其他的智能指針對象在維護(hù)著了。)
//因此,上面這兩句才是精髓。
m_pTObject = rhs.m_pTObject;
m_pCount = rhs.m_pCount;
return *this;
}
//->重載
T* operator -> ()
{
if (NULL != m_pTObject)
return m_pTObject;
throw runtime_error("access through NULL pointer");
}
const T* operator -> () const
{
if (NULL != m_pTObject)
return m_pTObject;
throw runtime_error("access through NULL pointr");
}
//*重載
T& operator * ()
{
if (NULL != m_pTObject)
return *m_pTObject;
throw runtime_error("dereference of NULL pointer");
}
const T& operator * () const
{
if (NULL != m_pTObject)
return &m_pTObject;
throw runtime_error("dereference of NULL pointer");
}
private:
//引用計數(shù)減1
void DoDecUseCount(void)
{
if (0 == --*m_pCount)
{
if (NULL != m_pTObject)
{
delete m_pTObject;
m_pTObject = NULL;
}
delete m_pCount;
m_pCount = NULL;
}
}
T* m_pTObject;
int* m_pCount;
}
//調(diào)用
/************************************************************************/
/** 智能指針
/************************************************************************/
// SmartPointerStu.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "SmartPointer.h"
#include <iostream>
using namespace std;
//一個測試智能指針的類
class CMyTestClass
{
public:
CMyTestClass() { cout << "A CMyTestClass Object was created." << endl; }
virtual void Print(void) { cout << "CMyTestClass Print()." << endl; }
virtual void Show(void) { cout << "CMyTestClass Show()." << endl; }
~CMyTestClass() { cout << "A CMyTestClass Object was destroied." << endl; }
};
class CMyTestSubClass : public CMyTestClass
{
public:
CMyTestSubClass() { cout << "A CMyTestSubClass Object was created." << endl; }
virtual void Print(void) { cout << "CMyTestSubClass Print()." << endl; }
void SubShow(void) { cout << "Sub Show()." << endl; }
~CMyTestSubClass() { cout << "A CMyTestSubClass Object was destroied." << endl; }
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
TSmartPtr<CMyTestClass> t; //因為沒有給t傳個CMyTestClass對象的指針參數(shù)進(jìn)去。所以會出異常。
t->Print();
}
catch(const exception& err)
{
cout << err.what() << endl;
}
//上面這個已經(jīng)測試通過了。結(jié)果正確。
//--------------------------------------
TSmartPtr<CMyTestClass> t1(new CMyTestClass);
t1->Print();
//上面這個測試->重載的操作符的正確性。測試結(jié)果是正確的。
TSmartPtr<CMyTestClass> t2(t1);
t2->Print();
//上面這個測試拷貝構(gòu)造函數(shù)的正確性。測試結(jié)果是正確的。
TSmartPtr<CMyTestClass> t3(new CMyTestClass);
t3 = t2;
(*t3).Print();
//上面這個測試=重載的操作符的正確性。測試結(jié)果也是正確的。
TSmartPtr<CMyTestSubClass> ts4(new CMyTestSubClass);
ts4->Print();
ts4->SubShow();
ts4->Show();
TSmartPtr<CMyTestSubClass> ts5(ts4);
ts5->SubShow();
TSmartPtr<CMyTestSubClass> ts6 = ts5;
ts6->Print();
//上面測試一下帶有繼承關(guān)系的類指針對象的智能指針使用。測試結(jié)果也是正確的。
system("pause");
return 0;
}
/** 智能指針
/************************************************************************/
// SmartPointerStu.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "SmartPointer.h"
#include <iostream>
using namespace std;
//一個測試智能指針的類
class CMyTestClass
{
public:
CMyTestClass() { cout << "A CMyTestClass Object was created." << endl; }
virtual void Print(void) { cout << "CMyTestClass Print()." << endl; }
virtual void Show(void) { cout << "CMyTestClass Show()." << endl; }
~CMyTestClass() { cout << "A CMyTestClass Object was destroied." << endl; }
};
class CMyTestSubClass : public CMyTestClass
{
public:
CMyTestSubClass() { cout << "A CMyTestSubClass Object was created." << endl; }
virtual void Print(void) { cout << "CMyTestSubClass Print()." << endl; }
void SubShow(void) { cout << "Sub Show()." << endl; }
~CMyTestSubClass() { cout << "A CMyTestSubClass Object was destroied." << endl; }
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
TSmartPtr<CMyTestClass> t; //因為沒有給t傳個CMyTestClass對象的指針參數(shù)進(jìn)去。所以會出異常。
t->Print();
}
catch(const exception& err)
{
cout << err.what() << endl;
}
//上面這個已經(jīng)測試通過了。結(jié)果正確。
//--------------------------------------
TSmartPtr<CMyTestClass> t1(new CMyTestClass);
t1->Print();
//上面這個測試->重載的操作符的正確性。測試結(jié)果是正確的。
TSmartPtr<CMyTestClass> t2(t1);
t2->Print();
//上面這個測試拷貝構(gòu)造函數(shù)的正確性。測試結(jié)果是正確的。
TSmartPtr<CMyTestClass> t3(new CMyTestClass);
t3 = t2;
(*t3).Print();
//上面這個測試=重載的操作符的正確性。測試結(jié)果也是正確的。
TSmartPtr<CMyTestSubClass> ts4(new CMyTestSubClass);
ts4->Print();
ts4->SubShow();
ts4->Show();
TSmartPtr<CMyTestSubClass> ts5(ts4);
ts5->SubShow();
TSmartPtr<CMyTestSubClass> ts6 = ts5;
ts6->Print();
//上面測試一下帶有繼承關(guān)系的類指針對象的智能指針使用。測試結(jié)果也是正確的。
system("pause");
return 0;
}