那我们面对这样的问题,该如何选择:
1.禁止复制
当资源管理类对象被复制时,如果不合理,我们就会选择禁止复制。可以将copying操作声明为private而不实现它,达到禁止的目的。(条款6中详细说了)
2.对底层资源祭出"引用计数法"
用一个变量保存引用个数,当引用个数为0时,才销毁它。这就是shared_ptr的做法(此外,shared_ptr允许指定删除器,当引用次数为0时,便会调用这个删除器)
3.复制底部资源
也就是"深度拷贝",不仅指针会被制作出一个复件,而且会创建一个新的内存。
4.转移底部资源的拥有权
简单点说,就是拥有权会从被复制的对象转移到复制的对象,而被复制的对象失去所有权,这是auto_ptr所实现的。
比如
[cpp
auto_ptr<int> t (new int);
auto_ptr<int> a = t;//所有权从t转向a,t将会指向NULL
条款15:在资源管理类中提供对原始资源的访问
我们需要面对的一个问题就是,现实中很多的API的参数直接涉及到资源,而我们把资源放在资源管理类中,因此我们需要提供对原始资源的访问。
[cpp]
auto_ptr<int> t(new int);
int test(int *t);//直接涉及资源
[cpp] view plaincopy
<pre></pre><span style="font-size:18px"><span style="font-family:Microsoft YaHei"></span></span>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
我们有两种方法来达到目标:显示转换和隐式转换
1.显示转换
通常的做法就是提供一个get()成员函数,返回资源。auto_ptr和shared_ptr就是这么做。
但是这么做的后果,就是会导致频频使用get()。
2.隐式转换
提供隐式转换函数
[cpp]
class Font {
public:
…
operator FontHandle() const { return f; } // 进行隐式转换的函数
…
};
但是会导致错误问题的增多:
[cpp]
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
FontHandle f2 = f1;//f1是一个Font对象
本来我只是想复制一个Font,但是不小心写成了FontHandle,这时候f2会隐式转换成FontHandle,再复制我的个人意见是,根据需要选择方法。