C++ 智能指针
C++ 智能指针
众所周知,C++和Java的最大的不同在于C++中有一个非常重要的工具——指针。成也萧何败萧何,指针的高效性和灵活性,同时也造成了C++的繁复而不易于管理。指针的管理一旦出现问题,轻则内存泄露,重则系统崩溃。为了应对指针所引起的内存泄露问题,在C++中一些所谓的智能指针异军突起。
一、STL中的实现auto_ptr
auto_ptr本质上是对基指针类型的进一步封装,从而能够对这些指针进行某种程度的更加安全的管理。
auto_ptr的最大的最大的优点是可以有效地应对异常中断问题,假设程序在运行过程当中遇到了异常,那么后面的代码将无法执行,包括了对已经申请的内存进行释放的代码。auto_ptr可以有效地解决这个问题。如下面的代码所示。
class test{ ... }; int main(){ test * t = new test(); //some operation here //but throws the exception delete t; return 0; }
如代码所示,程序在发生一场之后遇到的内存泄露场景。假设我们使用auto_ptr这种情况就不会发生。
class test{ ... }; int main(){ auto_ptr<test> t (new test()); //some operation here //but throws the exception return 0; }
就算发生异常,上面申请的内存任然可以被安全释放。因为t对象是放到栈上的,当它从作用域当中退出时,它的析构函数会被自动调用,从而释放它所管理的内存对象(及时发生异常,这个过程也会发生)
注意上面的auto_ptr的定义方式必须使用初始化的直接方式(也就是将参数传到紧跟在对象名后面的括号当中),因为他的构造函数是explicit的。
上面的规定是非常合理的,但是除却上面的规定,剩余的语法,让人感觉匪夷所思。
第一、复制和赋值都是破坏性的。当我们讲一个对象通过调用复制构造函数赋值给另一个auto_ptr时,会造成原来的auto_ptr的销毁,也就是它的基对象指针变成了未被绑定的状态。
auto_ptr<test> t(new test());auto_ptr<test> t1(t);这是我们可以测试t的绑定状态if(t.get()) cout<<"not null"<<endl;else cout<<"null"<<endl;上面的get的用法为,如果t为未绑定状态返回0,否则返回1。显然上面的代码返回的为0,输出 null。因为在复制操作中,它已经被重置为为绑定状态了。
对于赋值操作,具有同样的效果。
第二、release和reset
给人的直接感觉是release是释放内存的,但是事实上,它只是设置当前智能指针为未绑定状态,若要释放内存必须使用后面的reset方法。
即使release之后,我们仍然可以调用该对象的reset来释放内存。
auto_ptr<test> t(new test()); t.release();//the memory is not released t.reset();//the memory is released acutually
上面的reset还有其它的功能,比如我们可以将其指向一个新的内存指针,这同样是破坏性的。
假设刚开始auto_ptr没有绑定任何内存,则OK
如果绑定了任何一个指针,那么它会首先释放之。
正式基于auto_ptr的种种不便,boost库中的share_ptr兴起。
二、Boost shared_ptr
详细可以参考[1]
[1] http://www.cnblogs.com/TianFang/archive/2008/09/19/1294521.html
posted on 2015-06-09 15:14 lightblueme 阅读(241) 评论(0) 编辑 收藏 举报