说明:相关技术参考自:
http://www.cublog.cn/u/18517/showart_241240.html上面这个,写的真的很不错,通俗易懂。推荐大家去看下。下面是看完上面的文章后,自己尝试的:
//智能指针声明及实现
/************************************************************************/
/** 智能指针声明
/************************************************************************/
#pragma once
#include <iostream>
#include <stdexcept>
using namespace std;
#ifndef TEST_SMARTPTR
#define TEST_SMARTPTR
#endif
template < class T >
class TSmartPtr
{
public:
//默认构造函数
TSmartPtr(T* pTObject = NULL) : m_pTObject(pTObject), m_pCount(new int(1)) {}
//拷贝构造函数
TSmartPtr(const TSmartPtr& src) : m_pTObject(src.m_pTObject), m_pCount(src.m_pCount) { ++(*m_pCount); }
//析构函数
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; //源智能指针的引用计数增1
DoDecUseCount(); //目标智能指针的引用计数减1。此非常有必要。因为该指针既然要指向rhs,
//则说明它就不再想去管理自身原本的指针对象了。因此需要减1()
//在自身引用计数减1后,有可能自身原本维护的指针对象会被释放掉,也有可能不会。
//(因为,先前所管理的对象,有可能还有其他的智能指针对象在维护着了。)
//因此,上面这两句才是精髓。
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:
//引用计数减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;
}
//调用
/************************************************************************/
/** 智能指针
/************************************************************************/
// 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对象的指针参数进去。所以会出异常。
t->Print();
}
catch(const exception& err)
{
cout << err.what() << endl;
}
//上面这个已经测试通过了。结果正确。
//--------------------------------------
TSmartPtr<CMyTestClass> t1(new CMyTestClass);
t1->Print();
//上面这个测试->重载的操作符的正确性。测试结果是正确的。
TSmartPtr<CMyTestClass> t2(t1);
t2->Print();
//上面这个测试拷贝构造函数的正确性。测试结果是正确的。
TSmartPtr<CMyTestClass> t3(new CMyTestClass);
t3 = t2;
(*t3).Print();
//上面这个测试=重载的操作符的正确性。测试结果也是正确的。
TSmartPtr<CMyTestSubClass> ts4(new CMyTestSubClass);
ts4->Print();
ts4->SubShow();
ts4->Show();
TSmartPtr<CMyTestSubClass> ts5(ts4);
ts5->SubShow();
TSmartPtr<CMyTestSubClass> ts6 = ts5;
ts6->Print();
//上面测试一下带有继承关系的类指针对象的智能指针使用。测试结果也是正确的。
system("pause");
return 0;
}