如何在C ++中使数据所有权显式化

时间:2009-06-24 13:24:34

标签: c++

在C ++中使用指针和引用时,有时很难看出指针是否对引用的数据具有所有权,或者它是否只是时间引用。例如:

Instance* i = new Instance();
Instance* j = i;

如何弄清楚哪两个指针对实例拥有所有权?换句话说,如何明确哪个指针删除必须被调用?

注意:在上面的示例中,这不难看出,因为它是一段很短的代码。但是,当指针被复制并传递很多时,这可能会变得不清楚。

5 个答案:

答案 0 :(得分:7)

首先,使用引用来引用必须删除的数据似乎不必要地混淆。改为使用指针。

其次,如果要指示对象的所有权,请使用管理所有权的包装类。虽然它有缺点,但auto_ptr专门用于此目的。 (这些应该在下一版本的语言中由unique_ptr解决,但现在对你没有帮助。)

第三,在最简单的情况下(尽可能经常),不要直接使用堆。只需声明一个本地对象,例如

std::vector<int> v;

这并不会阻止您在需要时转移所有权(使用swap)。

答案 1 :(得分:7)

您无法确定所有者,因为没有内置机制来知道哪个指针拥有指针所指向的内存。

如果您真的关心这一点,您可以随时介绍自己的命名约定,例如:通过一些前/后修复您的变量名称。换句话说,您的代码设计可以为您提供此信息。由于您(和您的同事)正在编写代码,因此您始终可以确保在实现过程中强制执行此设计。这当然意味着每个人都必须遵循这些“规则”。

这是共同编码惯例如此重要的一个原因。所以你可以阅读你自己和其他人的代码并理解它。

答案 2 :(得分:3)

您可以使用shared_ptr<>之类的内容来明确共享所有权。如果你想保持一个明确的单一所有者与其他非所有者指针引用同一个对象,你可以使用类似boost::scoped_ptr<>的东西作为拥有指针,并为非拥有指针设置一个typedef:

typedef Instance* UnownedInstance_ptr;   // or some better name

这至少会记录意图。我不知道有什么方法可以避免删除包含指针的智能指针类型,并防止将指针复制到另一个获取所有权的智能指针(因为源代码没有任何内容)所有权放弃),但这可能是一个有趣的类来代表该政策。

答案 3 :(得分:3)

对我来说,我会选择匈牙利乐谱!

乔尔告诉你剩下的:: Making Wrong Code Look Wrong

你案子中的一个例子::

Instance* Owener_i = new Instance();
Instance* Observer_j = i;
.
.
.
.
.
delete Observer_j; // Wrong! not an Owner.

答案 4 :(得分:2)

正如其他人指出的那样 - 使用惯例。我使用原始指针作为非拥有变量,并且所有者通常被包装到某种智能指针(例如boost :: scoped_ptr)中,甚至不包含指针,除了在堆栈上创建的对象。