/*
* =====================================================================================
*
* Filename: smart_pointer.cpp
*
* Description: 智能指针学习
*
*
* Version: 1.0
* Created: 08/25/2012 08:48:12 PM
* Revision: none
* Compiler: g++
*
* Author: lsff (lsff),
*
*
* =====================================================================================
*/
#include <stdlib.h>
#include <iostream>
#include <cstdio>
using namespace std;
typedef int T; // 共享的东西的类型
/*
* 计数类: 存储核心指针,核心指针指向真正的数据
* 这个类是不做任何操作的
* 负责存放目前指向对象自身的指针个数及真正的指针
*/
class u_ptr
{
friend class HasPtr;
size_t use;
T* pCommon;
u_ptr(T* pCommon):pCommon(pCommon), use(1){}
~u_ptr() { if(pCommon) {cout<<"delete:"<<*pCommon<<endl;delete []pCommon; }pCommon=NULL;}
T*& operator->()
{
return pCommon;
}
};
/*
* 真正的智能指针:
* 负责对上面的计数指针进行维护
* 1) 这个智能指针可以像普通指针用
* 2)保证了2个点:指针赋值和初始化(用本类指针对象)
* 发生时,对维护的计数指针进行值复制的同时,记录了
* 所有指向计数指针个数
* 3)在对象的计数指针没有被其它对象指向的时候删除对象
* 好处: 避免野指针; 避免重复delete同一地址
*
* 其实可以把上面的计数类看作是数据类,而本类就是操作类
*/
class HasPtr
{
private:
u_ptr* ptr;
public:
/*
* 注意在四大函数对 计数类的维护
*/
HasPtr(T* p=NULL):ptr(new u_ptr(p)){} //允许指针值为NULL
~HasPtr() { if(ptr &&0==--(ptr->use)) delete ptr; } //
HasPtr(const HasPtr& orig): ptr(orig.ptr){ if(ptr)++ptr->use; } //this->().->use
HasPtr& operator=(HasPtr& );
HasPtr& operator=(T* pt); // 让智能指针更像普通的指针
u_ptr*& operator ->(){ return ptr;}
void showVal()const
{
printf("ptr: %p\tptr->use:%d\tptr->pCommon:%p\t*ptr->pCommon:%d\n", ptr,ptr->use,ptr->pCommon,*(ptr->pCommon));
}
};
HasPtr& HasPtr::operator=(HasPtr& rhs)
{
// cout<<"this->->use:"<<(this->operator->())->use<<endl; //可以
// cout<<"this->->use:"<<this->->use<<endl; //不可以
if(rhs.ptr) ++(rhs->use);
if(ptr&&0==--ptr->use){ delete ptr; ptr=NULL;}
this->ptr=rhs.ptr;
return *this;
}
HasPtr& HasPtr::operator=(T* pt)
{
HasPtr tmp = pt;
*this=tmp;
return *this;
}
class tst
{
private :
HasPtr sp;
public:
tst():sp(NULL){
sp=new T(4);
sp.showVal();
throw "构造函数时出错!";
}
~tst()
{
cout<<__FUNCTION__<<endl;
}
void show()
{
sp.showVal();
}
};
int main()
{
try{
tst tst1;
tst1.show();
tst tst2=tst1;
tst2.show();
HasPtr hp=new T(3);
*(hp->pCommon)=4;
}
catch(const char*e )
{
cout<<e<<endl; // 就算是构造函数中发生了异常,申请的堆空间也照样释放了
}
return 0;
}
再学智能指针
最新推荐文章于 2024-08-13 23:25:23 发布
本文介绍了智能指针的实现原理,包括计数类`u_ptr`和操作类`HasPtr`。`u_ptr`用于存储核心指针和使用计数,`HasPtr`则负责维护计数并确保在不再被引用时正确删除对象。通过这种方式,智能指针避免了野指针和重复删除的问题。示例中展示了如何使用`HasPtr`类,并在异常情况下确保资源的正确释放。
摘要由CSDN通过智能技术生成