理解智能指针(Smart Pointer)

来源:互联网 发布:手机淘宝查看历史评价 编辑:程序博客网 时间:2024/04/30 11:15

智能指针(smart ponter)是一项十分巧妙的C++编程技术,现在已经发展得相当成熟,运用也相当广泛。你一定对STL中的auto_ptr、shared_ptr毫不陌生,它们就是智能指针的具体实现。本文并不会详解auto_ptr和shared_ptr的语法,你可以在MSDN中轻轻松松查到,本文将主要分析智能指针的意义以及运用auto_ptr和shared_ptr的注意事项。

想一想那些没有智能指针的日子,面对愚笨的内建指针(built in pointer,又名dumb pointer),为了避免内存泄漏(memory leak),你必须小心翼翼地检查自己的代码,以确保new和delete每一次都成对出现。你一定同意这样的观点:代码复查的工作非常枯燥、低效且不靠谱。即使你有“火眼金睛”将代码仔细扫描了N遍并能够拍着胸膛保证new和delete无一落单,下面两种情况仍然会让你始料未及:

(1) 代码维护人员往往是另外一批人,它们没有参与程序的开发,因此很难全面理解代码上下文(context)的逻辑关联,代码维护人员很有可能在“一知半解”的情况下修改了程序的部分代码,影响了程序的预期执行路径;

(2) 程序中可能抛出某些异常,影响了程序的正常执行路径。

执行路径发生改变意味着delete语句很可能未被执行,看似成对出现的new和delete可能并没有成对地生效,从而导致分配的内存没能被释放,即发生内存泄漏。

不难看出,直接对内建指针做操作是非常低效、易错、麻烦的。智能指针解决了这个问题,它巧妙地运用了C++语言中自动调用析构函数的机制。将内建指针放入智能指针对象中,当智能指针对象跳出自己的作用域时,它的析构函数将被编译器自动调用。在智能指针的析构函数中对内存进行释放,从而确保内建指针所指向的内存不被泄漏。

STL中的auto_ptr和shared_ptr实现相似的功能,最大的差别在于auto_ptr的拷贝操作隐含着指针所有权的转移。auto_ptr的这种“异常”的行为是程序出现错误的一大隐患,使用时须特别小心。当你以by value方式将一个auto_ptr对象传递给函数时,你必须清楚实参一旦传入即变成null,因为实参的指针所有权转移给了函数的形参。你也不能将auto_ptr对象作为STL容器类的元素,因为STL容器类要求传统意义上的拷贝操作。你可以使用shared_ptr来避免这样的问题,shared_ptr是带引用计数的智能指针(reference-counting smart pointer),在拷贝时不会发生所有权的转移,更符合习惯上的拷贝意义。当然,你可以将shared_ptr对象作为STL容器类的元素。

auto_ptr和shared_ptr的析构函数用的都是delete,而非delete[],因此它们不能用于数组。STL只所有不提供专为数组服务的智能指针,是因为STL的vector和string很大程度上已经能够满足数组的需求。如果你仍然需要数组的智能指针,建议使用Boost库中的scoped_array和shared_array。

 

原创粉丝点击