关于智能指针的简单实现
其实关于指针是大的烦恼就是忘记删除New出来的内存,关于这点现在推出智能指针,
其实说白了就是把指针封装成一个类的对象,让类对像自动析构的时候删除指针
1.所以大致的类如下:
template<typename T>
class AiPtr //智能指针类模板
{
private:
T m_aiPtr;//保存外部要管理的指针
public:
AiPtr(T ptr){
m_aiPtr=ptr;
}
~AiPtr(){
if(m_aiPtr)//析构的时候自动删除管理的指针
delete m_aiPtr;
}
};
实例:
AiPtr<Student*> pAi= new Student(1,TEXT("张三"),TEXT("男"),34,56.7);
2.那么问题来了,这是管理外部的指针是没有问题的,
但是如果是外部的智能指针对象呢,你不可能删除别人的管理的指针吧
如:
AiPtr<Student*> p1=new Student;
AiPtr<Student*> p2=p1;
这个时候p2只是要用一个p1中的指针来获取数据,并不想删除其指针,
如果用前面的方法就是用完后删除了,p1的指针也就没有了,肯定要出问题的
所以,我想了个用一个bool变量来区分是自己管理的还是别人家的
修改如下:
template<typename T>
class AiPtr //智能指针类模板
{
private:
T m_aiPtr;//保存外部要管理的指针
bool m_bDelPtr; //是否要删除指针
public:
AiPtr(T ptr){
m_aiPtr=ptr;
m_bDelPtr=true; //自己管理的要删除
}
AiPtr(const AiPtr& aiPtr)
{
m_aiPtr=aiPtr.m_aiPtr;
m_bDelPtr=false; //管理别人的指针不删除
}
~AiPtr(){
if(m_aiPtr && m_bDelPtr)//析构的时候自动删除管理的指针
delete m_aiPtr;
m_aiPtr=nullptr;
}
3.重载->运算符号
既然说是指针,当然得有指针的->运算符号嘛
所以要重载->
operator->()const
{return m_aiPtr;}
//类对象转换为指针
operator T()const
{return m_aiPtr;}
//=号运算符
void operator=(const AiPtr& aiPtr)
{
m_aiPtr=aiPtr.m_aiPtr;
m_bDelPtr=false;
}
void operator=(T ptr)
{
m_aiPtr=ptr;
m_bDelPtr=true;
}
这是新new出来的默认构造Student类,其父类有个虚析构函数
这就不能删除了,
![](https://img-blog.csdnimg.cn/eb5729c87692455697d08780a58cd8a6.png
但是如果new的时候给类对象赋值就不会有这情况,这就能运行通过,也能删除,不知道因为啥?
6.场景运用
在某个函数中New了一个字符串指针 TCHAR* pstr=new CHAR[20];
赋值返回出来,我们用智能指针接收就不用担心指针释放的问题了
如:
TCHAR* GetString()const
{
TCHAR* pstr=new TCHAR[20];
lstrcpy(pstr,TEXT("我爱你中国");
return pstr;
}
//在外面用智能指针接收
AiPtr<TCHAR*> strAiPtr=GetString();
这样就不用管指针释放的问题了