【问题标题】:When returning a collection pointer, how does the client know if it needs to destroy it?返回集合指针时,客户端如何知道是否需要销毁它?
【发布时间】:2013-06-09 18:43:50
【问题描述】:

比如说我有原型:

QList<Foo *> *methodBar(int someParam);

此方法返回一个指向客户端代码的 QList 指针——客户端代码如何知道它是否需要销毁返回的指针?

有没有约定如果给你一个指针,控制它的内存是你的事?还是反过来?

我解决这个问题的想法是:

选项 1: 在文档块中记录它,客户端代码一旦完成就必须摆脱 QList。

选项 2 将签名更改为:

void methodBar(int someParam, QList<Foo *> &listForOutput);

以便客户端代码创建列表并且明确知道它应该在完成时将其销毁。

选项 3 使用某种智能指针,我不确定这是否有效,但如果我将QList* 包装在QPointer 中并返回QPointer 的副本,我认为它会浅复制内部QList* 然后当QPointer 超出客户端代码的范围时,它将与QList* 一起被销毁。

那么,这些选项中的哪一个(或者其他选项?)在 c++ 世界中是最常见的。如果没有这样做的标准方法,我会接受这取决于个人喜好的答案。

【问题讨论】:

  • 通常这是由命名约定来处理的。例如 cocoa(目标 c)使用 newXYZallocXYZcopyXYZmutableCopyXYZ 将其标记为调用者的责任。
  • 还有任何以const 返回的东西都保证是对象的责任,因为不允许调用者释放它(没有危险的强制转换)
  • 老实说,这与 Qt 关系不大,我会考虑删除 Qt 部分并使其成为更一般的 C++11 问题(使 QList 成为 std::vector 或类似的东西)。有关智能指针使用模式的更多参考,请参阅。 herbsutter.com/2013/05/29/gotw-89-solution-smart-pointersherbsutter.com/2013/06/05/… .
  • @peppe:感谢 Peppe 提供的这些链接。我同意这是一个通用的 c++ 问题,也许 Qt 元素和标签会产生噪音。我不确定我是否要编辑它,因为接受的答案也包含 Qt 元素,这可能会使事情有些脱节。如果版主认为最好同时更改两者,那么我对此没有问题。
  • 这正是避免使用原始指针而使用 smart_pointers 的原因。接口定义不明确。

标签: c++ qt smart-pointers qt5


【解决方案1】:

如果你想让调用者知道他们对指针负责,那么使用这个:

std::unique_ptr<QList<Foo *>> methodBar(int someParam);

另一个优点是调用者必须竭尽全力使内存不会被自动释放。

std::unique_ptr 不能被复制,只能移动,因此相当明确地传递 std::unique_ptr 会导致释放内存的责任从被调用者转移到调用者。

请注意,这也意味着列表中指向的对象不是调用者的责任。如果您希望这些对象也由调用者负责,您可以使用:

std::unique_ptr<QList<std::unique_ptr<Foo>>> methodBar(int someParam);

【讨论】:

  • 太好了,所以这有点像选项 3,但使用 std 智能指针而不是 Qt 智能指针。我现在可以看到“unique_ptr”的语义如何清楚地表明客户端代码被赋予唯一的副本,因此他们应该处理它。您对集合中 Foo 对象的介绍也很有用,谢谢。
  • 请注意将unique_ptr 存储在QList 中,我认为这实际上是不可能的,因为QList 不支持std::move 语义。它使用 std 集合(例如 std::deque)按预期运行:std::deque&lt;std::unique_ptr&lt;Foo&gt;&gt;
猜你喜欢
  • 2016-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多