将unique_ptr的向量传递给对象.向量成为成员变量.正确的方法
Passing a vector of unique_ptr to an object. the vector becomes a member variable. correct approach?
我将称之为"所有者"的一个对象,在其生命周期内拥有数据对象向量的明确所有权。
这些被存储为unique_ptr的向量。
一个名为"Output"的对象/类需要用许多不同的方法查看这些数据对象,因此某种引用/指针/变量是"Output"成员变量。
输出在其构造函数中接收数据对象的矢量。
我想了三种方法来实现这一点。什么是最好的方式?
选项1-"输出"对象将数据向量存储为常量引用:
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;
}
由"所有者"用实例化
data_vec_.push_back(std::unique_ptr<Data>(new Data));
/* stuff happens to data */
Output output(data_vec_);
选项2-"输出"对象将数据向量存储为常量指针:
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;
}
由"所有者"用实例化
data_vec_.push_back(std::unique_ptr<Data>(new Data));
/* stuff happens to data */
Output output(&data_vec_);
选项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;
};
由"所有者"用实例化
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中,是否清楚Output没有数据的所有权,即使它存储为unique_ptrs?选项3是否会在呼叫现场造成混乱?要达到同样的结果,还需要3行。
这里的最佳实践是什么?
如果你只需要"读取一些值,然后[创建]各种输出文件",我只需要让它成为一个通过const-ref:
void output(std::vector<std::unique_ptr<Data>> const& data) {
// stuff
}
在用法语义上,我更喜欢const&
而不是const*
(data[0]
和(*data)[0]
),而且肯定更喜欢两者都传递原始数据-不要白白放弃显式所有权(在这种情况下,这甚至不是为了方便,因为无论如何构造vector<Data*>
都很烦人)
由于您使用的是unique_ptr,您不打算与任何可能比Owner持续时间更长的数据共享此数据,因此简单的const引用应该很好。我推荐一个不错的typedef:
typedef std::vector<std::unique_ptr<Data>> OwnerDataSet;
Output(const OwnerDataSet &in)
方法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);
更进一步,从您的示例中还不清楚为什么要在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();
我将混合前两种方法:让Output构造函数通过const-ref获取向量,但将其存储为const指针。这是因为const指针可以被复制,因此如果需要,整个Output对象可以被赋值。
如果可能的话,我会完全避免传递向量,并将unique_ptr的向量封装在Owner
中。Output
是否可以具有指向Owner
的指针/引用,并从Owner
获取指向各个Data
元素的原始指针?
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...
}
};
- 向量成员在管理类指针C++队列时丢失
- C++:更新类的向量成员变量
- C++ 入门 12.1:我可以在类中使用静态向量成员实现 StrBlob<string> 吗?
- 具有向量成员的基类<int>
- C++ 向量::使用类对象迭代器擦除不擦除向量成员
- 无法将类构造函数中新创建的对象复制到 C++ 中的向量成员
- 修改另一个类的向量成员时出错
- 返回对私有向量成员元素的非常量引用是否是一种不好的做法
- 如何在 C++ 中将结构类型向量数据输入到结构向量成员(嵌套结构向量)中
- std::向量成员变量 EXC_BAD_ACCESS
- 如何使用其定义附近的显式长度/值构造函数初始化向量成员变量
- "Empty"数组\向量成员 C++
- 如何使用初始值设定项列表初始化 2D 向量成员
- 如何在类定义中初始化向量成员变量
- 如何初始化结构的向量成员
- 使用向量<向量>成员实例化对象时的隔离错误<int>
- 为向量成员和更新元素指定默认值
- 保持类的向量成员与类实例连续
- C++:在类构造函数中填充向量后,向量成员被销毁
- 通过引用另一个类方法传递向量成员变量