再学智能指针

来源:互联网 发布:正在识别网络 编辑:程序博客网 时间:2024/05/12 02:46
/* * ===================================================================================== * *       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->().->useHasPtr& 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;}