如何在所拥有的C ++对象中安全地存储对所有者的引用?

时间:2018-06-17 22:16:50

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

班级Owner通过Item拥有多个班级unique_ptr的对象。我希望Item的对象将引用(而不是指针)存储到拥有它们的Owner对象,具有以下要求:

  1. 永远不会有悬空参考。

  2. itm的{​​{1}}对象中包含的引用从不指向不属于Item的{​​{1}}对象。

  3. Owner对象始终拥有所有者。

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

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

1 个答案:

答案 0 :(得分:2)

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

这样Item只能在这里创建,而不能在其他任何地方创建。创建后,他们会直接获得Owner的引用。

Item中的引用始终有效,因为当Owner被破坏时,它所拥有的Item就会被破坏。

#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点的意思。