我将调用的一个对象"所有者",在其生命周期内拥有数据对象向量的明确所有权。
这些存储为unique_ptr的载体。
一个名为"输出"的对象/类需要以许多不同的方法查看这些数据对象,因此某种的引用/指针/变量是成员变量"输出"。
Output在其构造函数中接收数据对象的向量。
我想到了实现这一目标的三种方法。什么被认为是最好的方式?
选项1 - "输出" object将数据vec存储为const引用:
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;
}
由&#34;所有者&#34;实例化。用:
data_vec_.push_back(std::unique_ptr<Data>(new Data));
/* stuff happens to data */
Output output(data_vec_);
选项2 - &#34;输出&#34; object将数据vec存储为const指针:
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;
}
由&#34;所有者&#34;实例化。用:
data_vec_.push_back(std::unique_ptr<Data>(new Data));
/* stuff happens to data */
Output output(&data_vec_);
选项3 - &#34;输出&#34; object接收原始指针:
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;
};
由&#34;所有者&#34;实例化。用:
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);
其他查询: 在选项1和2中,很明显输出没有数据的所有权,即使它存储为unique_ptrs? 选项3是否在通话网站凌乱?需要3行才能达到相同的效果。
这里的最佳做法是什么?
答案 0 :(得分:3)
如果你需要的只是“读取一些值,然后[创建]各种输出文件”我会把它变成一个const-ref所需的函数:
void output(std::vector<std::unique_ptr<Data>> const& data) {
// stuff
}
我更喜欢const&
到const*
的使用语义(data[0]
vs (*data)[0]
),并且绝对更喜欢传递原始数据 - 不要放弃你的没有任何明确的所有权(在这种情况下,考虑到构建vector<Data*>
非常烦人,它甚至不方便)
答案 1 :(得分:2)
由于您使用的是unique_ptr,因此您不打算与可能持续时间超过Owner的任何内容共享此数据,因此简单的const引用应该是好的。我会推荐一个很好的typedef:
typedef std::vector<std::unique_ptr<Data>> OwnerDataSet;
Output(const OwnerDataSet &in)
方法1的优点是简单明了。其他人只是因为没有明显的原因而使其复杂化。
unique_ptr的功能是在std :: vector被破坏时删除新数据。这里的替代方法是复制Data实例而不是调用new。如果您不需要使用指针,那么您不需要像unique_ptr这样的特殊处理来保证它们的安全。
typedef std::vector<Data> OwnerDataSet;
OwnerDataSet results;
Data match = findoneresult();
results.push_back(match); // copy something from Owner
Output (results);
为了更进一步,从您的示例中不清楚为什么要在Output类之外维护std :: vector。由于您在传递的所有内容上调用std :: unique_ptr(new T),我怀疑您只将它与Output一起使用,因此您可以这样做:
class Output : public std::vector<Data> {
void PrintToScreen();
void WriteToDatabase();
void OrWhatever();
};
Output x;
Data match = findoneresult();
x.push_back(findoneresult());
x.PrintToScreen();
答案 2 :(得分:0)
我会混合前两种方法:让Output构造函数通过const-ref获取向量,但将其存储为const指针。这是因为可以复制const指针,以便在需要时可以分配整个Output对象。
答案 3 :(得分:0)
如果可能的话,我会避免传递向量,并将unique_ptr的向量封装在Owner
内。 Output
是否有指向Owner
的指针/引用并获取Data
中各个Owner
元素的原始指针?
class Owner {
private:
std::vector<std::unique_ptr<Data>> data_vec_;
public:
const Data* getData(size_t i) const { return data_vec_.at(i).get(); }
size_t getSize() const { return data_vec_.size(); }
};
class Output {
private:
const Owner& owner_;
public:
Output(const Owner& owner) : owner_(owner) { }
void doSomething() {
// get some data
auto data = owner_.getData(0);
// use data...
}
};