std :: unique_ptr

时间:2017-04-23 09:46:20

标签: c++ c++14 smart-pointers

有两个容器:资源的所有者和非所有者。由于我只有一个所有者,我想我需要unique_ptr。

class OwnershipContainer {
public:
    void add(std::unique_ptr<Obj> obj) {
        objects.push_back(std::move(obj));
    }
    Obj* get(std::size_t i) { return objects[i].get(); }
private:
    std::vector<std::unique_ptr<Obj>> objects;
};

我必须为非所有者容器使用哪种指针?首先想到的是原始指针。但是我不能保证Obj的寿命匹配或超过非所有者容器的寿命。

class NonOwnershipContainer {
public:
    void add(Obj *obj) {
        objects.push_back(obj);
    }
    Obj* get(std::size_t i) { return objects[i]; }
private:
    std::vector<Obj*> objects;
};

int main() {
    NonOwnershipContainer nonOwnershipContainer;
    {
        OwnershipContainer ownershipContainer;
        ownershipContainer.add(std::make_unique<Obj>(1));

        nonOwnershipContainer.add(ownershipContainer.get(0));
    }
    auto pobj = nonOwnershipContainer.get(0); // dangling pointer
}

我可以将shared_ptr用于owner,将weak_ptr用于非owner,因此我可以检查weak_ptr是否已过期。但是shared_ptr意味着我有共享所有权,在我的情况下不是这样,我不需要引用计数器。

编辑:

我不想延长寿命。当所有者容器被销毁时,我想避免悬空指针。正如我上面所写,我可以使用shared_ptr + weak_ptr。

class OwnershipContainer {
public:
    void add(std::shared_ptr<Obj> obj) {
        objects.push_back(obj);
    }
    std::shared_ptr<Obj> get(std::size_t i) { return objects[i]; }
private:
    std::vector<std::shared_ptr<Obj>> objects;
};


class NonOwnershipContainer {
public:
    void add(std::shared_ptr<Obj> obj) {
        objects.push_back(obj);
    }
    std::shared_ptr<Obj> get(std::size_t i) { return objects[i].lock(); }
private:
    std::vector<std::weak_ptr<Obj>> objects;
};

int main() {
    NonOwnershipContainer nonOwnershipContainer;
    {
        OwnershipContainer ownershipContainer;
        ownershipContainer.add(std::make_shared<Obj>(1));

        nonOwnershipContainer.add(ownershipContainer.get(0));
    }
    auto pobj = nonOwnershipContainer.get(0); // no more dangling pointer, pobj == nullptr
}

但是在这种情况下,我支付参考计数器,这在哲学上是错误的:只有一个所有者使用shared_ptr。

1 个答案:

答案 0 :(得分:3)

你实际上拥有共享所有权:当你通过NonOwningContainer包含类似指针的东西访问对象时,你必须取得所有权,否则对象可能会从你身下消失当你正在使用它时。

因为你不能保证对象不会从你身下消失:

  

但是我不能保证Obj的寿命匹配或超过非所有者容器的寿命。

那么你唯一的选择是分享所有权。因此,shared_ptrweak_ptr是合适的方法。

此外,根据OwnershipContainerNonOwnershipContainer的生命周期差异,请注意the interaction between std::make_shared and std::weak_ptr