关于智能指针(Smart Pointer)

Categories: 工具语言
Comments: No Comments
Published on: 2011 年 11 月 13 日

智能指针(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。

我猜你可能也喜欢:

No Comments - Leave a comment

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


Welcome , today is 星期日, 2017 年 12 月 17 日