智能指针的原理及其应用
所谓智能指针就是自动化管理指针所指向的动态资源的释放。
那么智能指针的引用是为了解决哪些问题呢?
代码中经常会忘掉释放动态开辟的资源,引用智能指针可用于动态资源管理,资源分配即初始化,定义一个类来封装资源的分配和释放,在构造函数中完成资源的分配和初始化,在析构函数完成资源的清理,可以保证资源的正确初始化和释放。
智能指针的原理:智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类是栈上的对象,智能指针指向堆上开辟的空间,函数结束时,栈上的函数会自动被释放,智能指针指向的内存也会随之消失,防止内存泄漏。
智能指针的实现需要实现构造、析构、拷贝构造、操作符重载。
几种常见的智能指针的区别?
auto_ptr:就是内部使用一个成员变量指向一块内存资源(构造函数),并且在析构函数中释放内存资源。auto_ptr的拷贝构造和赋值操作符重载函数所接受的参数都是非const的引用类型(即我们可以且修改资源),不能共享所有权(其它任意一个指针指向这块内存,它会把内存给别的指针,自己不指向了)。权限转移。
template<typenameT>classAuto_Ptr{public:Auto_Ptr(T*ptr=NULL):_ptr(ptr){}~Auto_Ptr(){if(_ptr!=NULL){delete_ptr;cout<<"~Auto_Ptr()"<<endl;}}Auto_Ptr(Auto_Ptr<T>&ap):_ptr(ap._ptr){ap._ptr=NULL;}Auto_Ptr<T>&operator=(Auto_Ptr<T>&ap){if(this!=&ap){delete_ptr;_ptr=ap._ptr;ap._ptr=NULL;}return*this;}private:T*_ptr;};voidTest1(){Auto_Ptr<int>a1(newint(1));Auto_Ptr<int>a2(a1);Auto_Ptr<int>a3(newint(2));a1=a1;a2=a3;}
scoped_ptr有着与auto_ptr类似的特性,scoped_ptr与auto_ptr最大的区别主要在于对内存资源拥有权的处理。(auto_ptr在拷贝构造时会从源auto_ptr自动交出拥有权,而scoped_ptr则不允许被拷贝)。scoped_ptr不能资源共享。
template<typenameT>classScoped_Ptr{public:Scoped_Ptr(T*ptr):_ptr(ptr){}~Scoped_Ptr(){if(_ptr!=NULL){delete_ptr;cout<<"~Scoped_Ptr()"<<endl;}}private:Scoped_Ptr(constScoped_Ptr<T>&sp);Scoped_Ptr<T>&operator=(constScoped_Ptr<T>&sp);T*_ptr;};voidTest2(){Scoped_Ptr<int>s1(newint(1));//Scoped_Ptr<int>s2(s1);Scoped_Ptr<int>s3(newint(2));//s1=s1;//s2=s3;}
shared_ptr就是为了解决auto_ptr在对象所有权上的局限性,在使用引用计数的基础上提供了可以共享所有权的智能指针。当新增一个shared_ptr对该对象进行管理时,就将该对象的引用计数加一,同理减少一个时,计数器减一。当该对象的引用计数器为0时,调用delete释放其所占的内存。
template<typenameT>classShared_Ptr{public:Shared_Ptr(T*ptr):_ptr(ptr),_count(newint(1)){}~Shared_Ptr(){if(--(*_count)==0){delete_ptr;delete_count;cout<<"~Shared_Ptr()"<<endl;}(*_count)--;}Shared_Ptr(Shared_Ptr<T>&sp):_ptr(sp._ptr),_count(sp._count){(*_count)++;}Shared_Ptr<T>&operator=(Shared_Ptr<T>&sp){if(this!=&sp){if(--(*_count)==0){delete_ptr;delete_count;}_ptr=sp._ptr;_count=sp._count;(*_count)++;}return*this;}private:T*_ptr;int*_count;};voidTest3(){Shared_Ptr<int>s1(newint(1));Shared_Ptr<int>s2(s1);Shared_Ptr<int>s3(newint(2));s1=s1;s1=s3;}
shared_ptr存在循环引用的问题,使用weak_ptr可以用来避免循环引用。但是weak_ptr对象引用资源时不会增加引用计数,无法知道资源会不会被突然释放,所以无法通过weak_ptr访问资源。在访问资源时weak_ptr必须先转化为shared_ptr。
#include<iostream>#include<boost/shared_ptr.hpp>#include<boost/weak_ptr.hpp>usingnamespacestd;usingnamespaceboost;structListNode{shared_ptr<ListNode>_prev;shared_ptr<ListNode>_next;//weak_ptr<ListNode>_prev;//weak_ptr<ListNode>_next;~ListNode(){cout<<"~ListNode()"<<endl;}};voidTest(){//循环引用问题shared_ptr<ListNode>p1(newListNode());shared_ptr<ListNode>p2(newListNode());cout<<"p1->Count:"<<p1.use_count()<<endl;cout<<"p2->Count:"<<p2.use_count()<<endl;//p1节点的_next指向p2节点p1->_next=p2;//p2节点的_prev指向p1节点p2->_prev=p1;cout<<"p1->Count:"<<p1.use_count()<<endl;cout<<"p2->Count:"<<p2.use_count()<<endl;}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。