C++内存管理学习笔记(5) (二)

2014-11-24 00:56:18 · 作者: · 浏览: 5
e_ptr
(1)boost中的智能指针

Boost提供了下面几种智能指针(Smart Pointers to boost your code):


将原文部分放上来,防止笔者翻译水平有限,影响大家阅读,请对照内容:

share_ptr 使用一个引用计数器来判断此指针是不是需要被释放。是boost中最常用的智能指针了。
scope_ptr 当这个指针的作用域消失之后自动释放,性能与内置的指针差不多
intrusive_ptr 也维护一个引用计数器,比shared_ptr有更好的性能。但是要求T自己提供这个引用计数机制。
weak_ptr 弱指针,要和shared_ptr 结合使用避免循环引用
share_array 和shared_ptr相似,但是访问的是数组
scope_array 和scoped_ptr相似,但是访问的是数组

(2)share_ptr引入

首先,我们通过例子来了解这个智能指针,

1: void Sample_Shared() 2: { 3: // (A) create a new CSample instance with one reference 4: boost::shared_ptr mySample(new CSample); 5: printf("The Sample now has %i references\n", mySample.use_count()); // should be 1 6: 7: // (B) assign a second pointer to it: 8: boost::shared_ptr mySample2 = mySample; // should be 2 refs by now 9: printf("The Sample now has %i references\n", mySample.use_count()); 10: 11: // (C) set the first pointer to NULL 12: mySample.reset(); 13: printf("The Sample now has %i references\n", mySample2.use_count()); // 1 14: 15: // the object allocated in (1) is deleted automatically 16: // when mySample2 goes out of scope 17: }

在代码块(A)中,在堆中创建一个CSample对象,通过绑定share_ptr指针到mySample,如下图示:


(B)中我们通过另外一个mySample2指针指向这个对象,如下图示:


之后(C),reset操作第一个指针对象(p=NULL),但是CSample对象没有被释放,因为它mySample2在引用。


只有当最后的引用释放掉后,出了当前作用域时,CSample对象的内存被释放掉。


下面是shared_ptr一些应用案例:

use in containers
using the pointer-to-implementation idiom (PIMPL)
Resource-Acquisition-Is-Initialization (RAII) idiom
Separating Interface from Implementation
1>在容器中使用;

2>PIMPL(pointer to implementation)惯例,即“实现的指针较短”;

3>RAII()惯例; (详细讲解见《学习笔记(4)》)

4>类的使用接口和实现分离

小知识: PIMPL idiom与RAII idiom

1.RAII

RAII是Bjarne Stroustrup教授用于解决资源分配而发明的技术,资源获取即初始化。RAII是C++的构造机制的直接使用,即利用构造函数分配资源,利用析构函数来回收资源.

2.PIMPL

PIMPL是一种应用十分广泛的技术,它的别名也很多,如Opaque pointer, handle classes等。PIMPL是RAII的延展,籍由RAII对资源的控制,把具体的数据布局和实现从调用者视线内移开,从而简化了API接口,也使得ABI兼容变得有可能,Qt和KDE正是使用Pimpl来维护ABI的一致性,另外也为惰性初始化提供途径,以及隐式共享提供了基础。

详细介绍参考:http://c2.com/cgi/wiki PimplIdiom或者wiki;

PIMPL或者RAII是C++程序中众所周知的重要概念, 智能指针只是实现这两种惯用手法的一种方式.

(If you never heard of PIMPL (a.k.a. handle/body) or RAII, grab a good C++ book - they are important concepts every C++ programmer should know. Smart pointers are just one way to implement them conveniently in certain cases)


(3)share_ptr的特点

这里引用《Smart Pointers to boost your code》一文中对share_ptr特点的描述,

shared_ptr works with an incomplete type:
When declaring or using a shared_ptr, T may be an "incomplete type". E.g., you do only a forward declaration usingclass T;. But do not yet define howT really looks like. Only where you dereference the pointer, the compiler needs to know "everything".

shared_ptr works with any type:
There are virtually no requirements towards T (such as deriving from a base class).

shared_ptr supports a custom deleter
So you can store objects that need a different cleanup than delete p. For more information, see the boost documentation.

Implicit conversion:
If a type U * can be implicitly converted to T * (e.g., becauseT is base class ofU), a shared_ptr can also be converted toshared_ptr implicitly.

shared_ptr is thread safe
(This is a design choice rather than an advantage, however, it is a necessity in multithreaded programs, and the overhead is low.)

Works on many platforms, proven and peer-reviewed, the us