在编写C++程序的时候,让我们最头痛的问题就是内存泄露,也就是说:int*pt=newint;deletept;必须保证new和delete必须成对出现。作为程序员,我们最理想的指针,是可以像使用普通变量一样来使用的指针,这个指针可以在恰当的时候被自动释放。智能指针就是这样的一个指针,它的任务是要保证每一个被动态分配的内存块都能够被释放。就像我们在写handle=CreateSession(...);和CloseSession(handle);的时候,因为要保证这两者成对出现,我们****惯的做法是将其分别放在一个类的构造和析构函数当中。这样,就能保证每一个CreateSession都有对应的CloseSession了。同样,为了保证new和delete的成对出现,智能指针也采用同样的做法——分别放在构造和析构函数中去。classintptr{private:int*m_p;public:intptr(int*p){m_p=p;}~intptr(){deletem_p;}int&operator*(){return*m_p;}};我们可以方便的执行以下代码,而不必担心内存泄漏的问题:somefunction(){intptrpi(newint);*pi=10;inta=*pi;…………}以上我们给出的“智能指针”有个致命错误。设想我们执行以下代码会有怎样的情况发生:voidsomefunction(){intptrpt1(newint);intptrpt2(newint);*pt1=10;pt2=pt1;}对于普通指针来说,pt2=pt1只是让pt2指向与pt1相同的地址,但是对于我们的智能指针来说,pt2原先指向的地址被泄露掉了,而pt1所指向的地址被释放了两次。所以,我们给每个new出来的内存地址对应的分配一个“被指向计数器”,由它记录这块内存地址被多少指针所指向。※每当一个新的“智能指针”指向一块“内存地址”的时候,这块“内存地址”对应的“被指向计数器”自增1;每当一个“智能指针”的生命周期结束或者指向其它“内存地址”的时候,这块“内存地址”对应的“被指向计数器”自减1,此时,如果该“被指向计数器”的计数值为0,也就是说不再有任何“智能指针”指向这块“内存地址”时,则将这个“内存地址”释放掉。于是我们得到这样一个“智能指针”,它已经可以满足我们对intptr类型的全部需要了:classintptr{private:size_t*m_count;int*m_p;public:intptr(int*p){m_p=p;m_count=newsize_t; //建立一个计数器*m_count=1; //初始化计数值为printf("smartpointercreated.\n");}intptr(constintptr&rhs) //拷贝构造函数{m_p=; //指向同一块内存m_count=; //使用同一个计数器(*m_count)++; //计数器自增printf("newsmartpointeradded.\n");}~intptr(){(*m_count)--; //计数器自减if(*m_count==0) //已经没有别的指针指向该内存块了{deletem_p;deletem_count;printf("smartpointerremovedandmemorydeleted\n");}else{printf("smartpointerremoved\n");}}intptr&operator=(constintptr&rhs){if(m_p==)return*this;//是否本来就指向同一内存块,是则返回(*m_count)--; //原内存块计数器减if(*m_count==0) //是否已经没有别的指针指向原内存块了{deletem_p;deletem_count;printf("originalmemorydeleted\n");}m_p=; //指向同一内存块m_count=; //使用同一个计数器(*m_count)++; //计数器加printf("newsmartpointeraddedtocurrentmemory\n");return*this;}int&operator*(){return*m_p;}};于是当我们执行以下代码时,我们可以得到这样的结果:voidsomefunction(){intptrpt1(newint);*pt1=10;intptrpt2=pt1;printf("%d\n",*pt2);intptrpt3(newin
智能指针原理 来自淘豆网www.taodocs.com转载请标明出处.