【问题标题】:How to safely store a reference to owner in an owned C++ object?如何在拥有的 C++ 对象中安全地存储对所有者的引用?
【发布时间】:2018-06-17 22:16:49
【问题描述】:

Owner 类通过unique_ptr 拥有Item 类的多个对象。我希望Item 的对象存储对拥有它们的Owner 对象的引用(而不是指针),并满足以下要求:

  1. 永远不能有悬空引用。

  2. Item 类的itm 对象中包含的引用永远不会指向不拥有itmOwner 对象。

  3. Item 对象总是有一个所有者。

  4. Item 类将通过其子类使用。

我尝试在构造过程中自动注册Item 类的对象(在Item::Item() 中),但是在堆栈上创建它们时会导致双重删除。因此,我可能需要防止在堆栈上创建它们。但是当我对它们进行子类化时,这是一个问题。有没有更简单的方法来确保相互链接始终正确,而不放宽任何要求?我怀疑 3. 可能必须放宽,以便先创建对象并稍后将其注册到 Owner

【问题讨论】:

  • 我的问题有什么不清楚的地方?任何澄清建议都非常受欢迎。
  • 恕我直言,如果 Items 是在堆栈上创建的,并且我认为堆栈是指它们具有自动存储功能,那么 Owner 并不真正拥有它们,至少在资源方面是这样。除此之外,Item 中对 Owner 的引用似乎符合要求。
  • 谢谢。因此,为了确保Item 始终归Owner 所有,我必须阻止Item 的自动存储?
  • 如果您确保只允许Owner 构造Item,并且在构造时将引用传递到Item,则应涵盖所有要点。
  • 您是否确定 Item 实际上需要 存储反向引用?还是可以通过您访问它的方式提供?

标签: c++ reference unique-ptr ownership-semantics


【解决方案1】:

为了详细说明我的评论,如果您将Items 构造函数设为私有,并在构造时引用所有者。然后您可以将Owner 设为朋友类,或者如我的示例中将Owners 函数之一设为朋友函数。

这种方式Items 只能在此处创建,而不能在其他任何地方创建。当它们被创建时,它们会直接获得对 Owner 的引用。

Item 中的引用将始终有效,因为当 Owner 被销毁时,它拥有的 Items 也会随之销毁。

#include <iostream>
#include <vector>
#include <memory>

class Item;

class Owner {
    public:
    std::vector<std::unique_ptr<Item>> foos;

    void makeItem();
};

class Item {
    Item(Owner& b) : owner(b) {}

    friend void Owner::makeItem();
    Owner& owner;
};

void Owner::makeItem() {
    foos.emplace_back(new Item(*this));
}

int main() {
    Owner b;
    //Item item(b); not allowed, constructor is private
    b.makeItem();
}

不完全确定您对第 4 点的意思。

【讨论】:

  • 我怀疑Foo 将是一个基类。您的示例可能必须进行调整以允许创建自定义Foos,但我想模仿stdemplace 是可能的并且相对容易。
  • @luk32 你可能是对的。我不清楚 OP 的意图是什么,或者 Items 的用法,所以我把它省略了。
猜你喜欢
  • 2012-06-11
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多