具有实物代表的所有权

时间:2018-11-23 09:43:10

标签: c++ c++14 shared-ptr smart-pointers ownership

在阅读RAII,查看Herb Sutter's CppCon2014 presentation并阅读core guidelinesrelated articles之后的几天里,我仍然对所有权和相关语义。

假设A类和B类代表物理实体,并且有一个Scene类和一个Process类。如果可以,Process类是main函数。在现实世界中,A可以获取B并实际保留它。它也可以释放它。因此,在Process实例的过程中,A对象必须能够拥有一个B实例,并且必须在完成该实例后将其释放。 As和Bs生活在一个场景中,流程必须对此进行管理。

也派生了B:A使用某些接口,而Scene使用B提供的其他接口。

让我们至少为该流程尝试一些代码:

class Process
{
public:
  void run();
};

void Process::run()
{
  auto scn = Scene {};
  auto a = A {};
  auto b = B {};

  scn.add(a);  // stores a
  scn.add(b);  // stores b

  a.acquire(b);  // stores b, and represents physical possession of a B
  a.doSomething();
  a.release(b);  // sets a's B instance to null, and physically loses the B
}

如果我错了,请在这里纠正我,这是可疑的部分。

据我了解,A应该(而不是像代码一样)在堆上并从shared_ptr指向,因为Process和Scene都有它们自己的A实例。B也会发生同样的情况,存储在ascn中,并且正在处理 。那么为什么scn不会make_unique

另一种方法是将所有内容都放在堆栈中(如代码片段中所示)。这两种解决方案对我来说似乎都是相同的,我完全不了解这两种选择的语义差异,但是我倾向于第一种。

1 个答案:

答案 0 :(得分:3)

C ++所有权实质上可以归结为“谁负责删除这个特定对象,如果它们在这个特定时刻死亡”。在您的示例中,由于所有对象都有自动生存期,因此它们全部由Process::run自己拥有。 addacquirerelease中没有任何所有权转让。

现在,动态生命周期对象又如何处理呢?您的描述(我假设C的意思是Scene)仍然可以通过两种不同的方式实现:

  • Scene拥有std::unique_ptr的{​​{1}},这是给定的
  • AScene可以将 {em> Astd::unique_ptr保留到std::shared_ptr

可以通过上面概述的所有权的定义来做出第二个项目符号的选择。当B握住A而死亡时会发生什么?

  • 如果B也应死,那么B是其唯一所有者,应通过A持有
  • 如果std::unique_ptr应该保留在B内,则SceneScene都是所有者,并且都应通过{{ 1}}

这不包括非所有权(原始)指针,这很有用(例如,如果A拥有B,但std::shared_ptr仍然需要直接引用,无论如何目的)。这些必须分别更新。