16.5 打开和关闭所有权

让我们回到所有权问题上来。以值包含对象的容器通常无须担心所有权问题,因为它们清晰地拥有它们所包含的对象。但是,如果容器内包含指向对象的指针(这种情况在C++中相当普遍,尤其在多态情况下),而这些指针很可能用于程序的其他地方,那么删除该指针指向的对象会导致在程序的其他地方的指针对已销毁的对象进行引用。为了避免上述情况,在设计和使用容器时必须考虑所有权问题。

许多程序都比这个问题更简单,并且不会遇到所有权问题:一个容器所包含的指针指向仅由这个容器使用的那些对象。在这种情况下,所有权简单而直观:该容器拥有它自己的对象。

处理所有权问题的最好方法是由客户程序员来选择。这常常通过构造函数的一个参数来完成,它默认地指明所有权(简单情况)。另外还有“读取”和“设置”函数用来查看和修正容器的所有权。如果容器内有用于删除对象的函数,容器所有权的状态通常会影响这个删除,所以我们还可以找到在删除函数中控制销毁的选项。我们可以对容器中的每一个成员添加所有权数据,这样每个位置都知道它是否需要被销毁;这是一个引用计数的变体,在这里是容器而不是对象知道所指对象的引用数。

16.5 打开和关闭所有权 - 图1

16.5 打开和关闭所有权 - 图2

默认行为是让容器去销毁它的对象,但我们可以通过修改构造函数的参数或者使用owns()读/写成员函数来改变这个行为。

正如我们可能看到的大多数模板那样,整个实现包含在头文件中。下面是一个检验所有权能力的小测试。

16.5 打开和关闭所有权 - 图3

ac2对象不拥有放在它里面的对象,因而ac就是对所有权员有责任的“主”容器。在容器生命期内如果希望改变一个容器拥有它的对象,我们可以用owns()做这件事。

我们还有可能改变所有权的粒度,使得它以“object-by-object”为基础,但是这将可能会使所有权问题的解决更趋复杂。