C++智能指针实现方法

本文介绍了一种智能指针的实现方式,并通过具体的代码示例展示了如何使用该智能指针来管理动态分配的对象。文章涵盖了智能指针的基本概念、构造函数、析构函数、赋值运算符重载及箭头运算符重载等关键特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#pragmaonce

#include
<iostream>
#include
<stdexcept>
usingnamespacestd;

#ifndefTEST_SMARTPTR
#defineTEST_SMARTPTR
#endif

template
<classT>
classTSmartPtr
{
public:
//默认构造函数
TSmartPtr(T*pTObject=NULL):m_pTObject(pTObject),m_pCount(newint(1)){}
//拷贝构造函数
TSmartPtr(constTSmartPtr&src):m_pTObject(src.m_pTObject),m_pCount(src.m_pCount){++(*m_pCount);}
//析构函数
virtual~TSmartPtr()
{
#ifdefTEST_SMARTPTR
cout
<<"SmartPtrObjectFree."<<endl;
#endif
DoDecUseCount();
}
//=重载
TSmartPtr&operator=(constTSmartPtr&rhs)
{
//self-assigningisalsoright
++*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)
returnm_pTObject;
throwruntime_error("accessthroughNULLpointer");
}
constT*operator->()const
{
if(NULL!=m_pTObject)
returnm_pTObject;
throwruntime_error("accessthroughNULLpointr");
}
//*重载
T&operator*()
{
if(NULL!=m_pTObject)
return*m_pTObject;
throwruntime_error("dereferenceofNULLpointer");
}
constT&operator*()const
{
if(NULL!=m_pTObject)
return&m_pTObject;
throwruntime_error("dereferenceofNULLpointer");
}
private:
//引用计数减1
voidDoDecUseCount(void)
{
if(0==--*m_pCount)
{
if(NULL!=m_pTObject)
{
deletem_pTObject;
m_pTObject
=NULL;
}
deletem_pCount;
m_pCount
=NULL;
}
}
T
*m_pTObject;
int*m_pCount;
}

//调用
/************************************************************************/
/**智能指针
/***********************************************************************
*/

//SmartPointerStu.cpp:Definestheentrypointfortheconsoleapplication.
//

#include
"stdafx.h"

#include
"SmartPointer.h"
#include
<iostream>
usingnamespacestd;

//一个测试智能指针的类
classCMyTestClass
{
public:
CMyTestClass(){cout
<<"ACMyTestClassObjectwascreated."<<endl;}
virtualvoidPrint(void){cout<<"CMyTestClassPrint()."<<endl;}
virtualvoidShow(void){cout<<"CMyTestClassShow()."<<endl;}
~CMyTestClass(){cout<<"ACMyTestClassObjectwasdestroied."<<endl;}
};

classCMyTestSubClass:publicCMyTestClass
{
public:
CMyTestSubClass(){cout
<<"ACMyTestSubClassObjectwascreated."<<endl;}
virtualvoidPrint(void){cout<<"CMyTestSubClassPrint()."<<endl;}
voidSubShow(void){cout<<"SubShow()."<<endl;}
~CMyTestSubClass(){cout<<"ACMyTestSubClassObjectwasdestroied."<<endl;}
};

int_tmain(intargc,_TCHAR*argv[])
{
try
{
TSmartPtr
<CMyTestClass>t;//因为没有给t传个CMyTestClass对象的指针参数进去。所以会出异常。
t->Print();
}
catch(constexception&err)
{
cout
<<err.what()<<endl;
}
//上面这个已经测试通过了。结果正确。
//--------------------------------------
TSmartPtr<CMyTestClass>t1(newCMyTestClass);
t1
->Print();
//上面这个测试->重载的操作符的正确性。测试结果是正确的。
TSmartPtr<CMyTestClass>t2(t1);
t2
->Print();
//上面这个测试拷贝构造函数的正确性。测试结果是正确的。
TSmartPtr<CMyTestClass>t3(newCMyTestClass);
t3
=t2;
(
*t3).Print();
//上面这个测试=重载的操作符的正确性。测试结果也是正确的。

TSmartPtr
<CMyTestSubClass>ts4(newCMyTestSubClass);
ts4
->Print();
ts4
->SubShow();
ts4
->Show();
TSmartPtr
<CMyTestSubClass>ts5(ts4);
ts5
->SubShow();
TSmartPtr
<CMyTestSubClass>ts6=ts5;
ts6
->Print();
//上面测试一下带有继承关系的类指针对象的智能指针使用。测试结果也是正确的。

system(
"pause");
return0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值