c++ - 传递 unique_ptr<T> 的 C++ vector 而不传递所有权

标签 c++ c++11 move smart-pointers unique-ptr

我有一个 Outer 类,它包含一个 Inner 成员并且拥有一个 unique_ptr 元素的 vector :

using Elements = std::vector<std::unique_ptr<Element>>;

class Outer
{
    void call()
    {
        _inner.aMethod(_vec);
    }

    Inner _inner;
    Elements _vec;   // This should remain the owner of each Element
};

Inner 接收 unique_ptr 元素的 vector ,并将所有权转移给它自己的 vector 类成员:

class Inner
{
    public:
    Inner() = default;
    ~Inner() = default;

    void aMethod(Elements& vec)
    {
        _vec = std::move(vec);
    }

    private:

    Elements _vec;  // This is a vector of unique_ptr but I don't want this class to own the memory
};

我愚蠢地使用了 std::move(),否则编译器会提示我试图在每个 vector 元素上调用已删除的函数(可能是复制构造函数)。

我有一个非法的内存访问,我相信这是因为两个类都认为它们拥有 vector 元素,并且一个类试图删除一个已经删除的 Element

如何让 Outer 拥有内存并将元素传递给 Inner 使用(不取得所有权)?

最佳答案

你不能有两个 std::unique_ptr s 指向同一个对象。 unique_ptr暗示独特所有权。

如果您需要共享所有权,请使用 std::shared_ptr相反。在您的示例中,它应该是一个直接替换,只需更改 using声明:

using Elements = std::vector<std::shared_ptr<Element>>;

如果你不想Inner对象拥有其 _vec 指向的对象成员,那么它应该是一个原始指针 vector :

class Outer
{
    void call()
    {
        std::vector<Element*> observer;
        std::transform(_vec.begin(), _vec.end(), std::back_inserter(observer),
                       [](std::unique_ptr<Element>& el) { return el.get(); });
        _inner.aMethod(observer);
    }

    //...
};

class Inner
{
    // ...

    void aMethod(std::vector<Element*> vec)
    {
        _vec = std::move(vec);
    }

private:
    std::vector<Element*> _vec;
};

当然,这样做意味着您冒着离开的风险 _vec如果 Outer 的元素悬空释放任何 Element它拥有而无需更新任何Inner指向它们的对象。您可以通过存储指向 Outer 的指针来部分减轻这种风险。对象而不是直接存储指向 Element 的指针小号:

class Outer
{
    void call()
    {
        _inner.aMethod(this);
    }

    //...
};

class Inner
{
    // ...

    void aMethod(Outer* outer)
    {
        outer_ = outer;
    }

private:
    Outer* outer_;
};

Inner然后只会访问它的 Element通过 Outer对象(如有必要,您可以将 Inner 设为 friendOuter)。这仍然存在 Inner 的可能性对象可能比 Outer 更长寿它指向的对象,但它确实在一定程度上降低了风险。

关于c++ - 传递 unique_ptr<T> 的 C++ vector 而不传递所有权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56779682/

相关文章:

c++ - MS Visual Studio 2013 上的 std::reference_wrapper

c++ - std::list 提示缺少第二个模板参数(分配器)

c++ - 使用像 std::string 这样有趣的类型来保存一些标记类型

java - 应该 move 球的程序,但不执行方法运行

excel - VBA向上/向下 move 选定范围(有偏移?)

c++ - cv::viz::Widget 是否可点击? (OpenCV C++)

C++:调用模板类的非模板函数

c++ - c++98 中的 move() 是什么?

c++ - 从 C++ "time.h"测量的运行时间是实际运行时间的两倍

c++ - 试图让 Qt4 示例在安装了 Qt Creator 4 的 ubuntu 10.10 上运行