将 unique_ptr 的向量传递给对象。该向量成为一个成员变量。正确的做法?

win*_*rgy 5 c++ oop c++11

我将称之为“所有者”的一个对象在其生命周期内拥有数据对象向量的明确所有权。

这些存储为 unique_ptr 的向量。

一个对象/类,称为“输出”,需要以许多不同的方法查看这些数据对象,因此某种引用/指针/变量是“输出”的成员变量。

输出在其构造函数中接收数据对象的向量。

我已经想到了三种方法来实现这一目标。什么会被认为是最好的方法?

选项 1 - “输出”对象将数据 vec 存储为常量引用:

class Output {
    // output wants the data:
 public:
    Output(std::vector<std::unique_ptr<Data>> const & in)
        : my_lot_of_data(in) {
    };
    std::vector<std::unique_ptr<Data>> const & my_lot_of_data;
}
Run Code Online (Sandbox Code Playgroud)

它由“所有者”实例化:

 data_vec_.push_back(std::unique_ptr<Data>(new Data));
 /* stuff happens to data */
 Output output(data_vec_);
Run Code Online (Sandbox Code Playgroud)

选项 2 - “输出”对象将数据 vec 存储为常量指针:

class Output {
    // output wants the data:
 public:
    Output(std::vector<std::unique_ptr<Data>> const * in)
        : my_lot_of_data(in) {
    };
    std::vector<std::unique_ptr<Data>> const * my_lot_of_data;
}
Run Code Online (Sandbox Code Playgroud)

它由“所有者”实例化:

 data_vec_.push_back(std::unique_ptr<Data>(new Data));
 /* stuff happens to data */
 Output output(&data_vec_);
Run Code Online (Sandbox Code Playgroud)

选项 3 - “输出”对象接收原始指针:

class Output {
    // output wants the data:
 public:
    Output(std::vector<Data*> in)
        : my_lot_of_data(in) {
    };
    std::vector<Data*> const my_lot_of_data;
};
Run Code Online (Sandbox Code Playgroud)

它由“所有者”实例化:

 data_vec_.push_back(std::unique_ptr<Data>(new Data));
 /* stuff happens to data */
 std::vector<Data*> data_as_raw;
 data_as_raw.resize(data_vec_.size());
 std::transform(data_vec_.begin(), data_vec_.end(), data_as_raw.begin(), [](std::unique_ptr<Data> const & x) {return x.get();});
 Output output(data_as_raw);
Run Code Online (Sandbox Code Playgroud)

附加查询:在选项 1 和 2 中,是否清楚输出不拥有数据的所有权,即使它存储为 unique_ptrs?选项 3 在呼叫站点上是否混乱?还需要 3 行才能达到相同的结果。

这里的最佳实践是什么?

Ken*_*rom 2

由于您使用的是 unique_ptr,因此您不打算与任何可能比 Owner 持续时间更长的东西共享此数据,因此简单的 const 引用应该很好。我会推荐一个不错的 typedef:

typedef std::vector<std::unique_ptr<Data>> OwnerDataSet;
Output(const OwnerDataSet &in)
Run Code Online (Sandbox Code Playgroud)

方法1的优点是简单明了。其他人只是无缘无故地让事情变得复杂。

unique_ptr的作用是在std::vector被析构时删除新的Data。这里的替代方法是复制 Data 的实例而不是调用 new。如果您不需要使用指针,那么您不需要像 unique_ptr 这样的特殊处理来保证它们的安全。

typedef std::vector<Data> OwnerDataSet;
OwnerDataSet results;
Data match = findoneresult();
results.push_back(match); // copy something from Owner
Output (results);
Run Code Online (Sandbox Code Playgroud)

更进一步,从您的示例中不清楚为什么要在 Output 类之外维护 std::vector 。由于您在传递的所有内容上调用 std::unique_ptr(new T) ,我怀疑您只将它与输出一起使用,因此您可以这样做:

class Output : public std::vector<Data> {
    void PrintToScreen();
    void WriteToDatabase();
    void OrWhatever();
};

Output x;
Data match = findoneresult();
x.push_back(findoneresult());
x.PrintToScreen();
Run Code Online (Sandbox Code Playgroud)