此代码会爆炸,对吗?一旦循环退出,原始实例将与其所有内部成员一起死亡,因此如果它们不是POD,任何需要访问do_stuff
成员的B
方法都会引发分段错误,正确的吗?
void foo() {
std::vector<B> bar;
for (int i = 0; i < 7; i++)
bar.push_back(B(i, i, i));
bar[3].do_stuff();
}
那么,有没有办法在不使用指针的情况下执行此操作? 或者你必须这样做:
void foo() {
std::vector<B*> bar;
for (int i = 0; i < 7; i++)
bar.push_back(new B(i, i, i));
bar[3]->do_stuff();
for (int i = 0; i < 7; i++)
delete bar[i];
}
答案 0 :(得分:12)
第一个代码示例有效。
std::vector
将复制您使用push_back
传递的对象(或者移动它们与C ++ 11一起使用如果你正在推动一个临时的),只要向量本身存活,它就会保持所有实例的存活。
退出函数时会发生破坏,而不是退出循环时。
答案 1 :(得分:7)
第一个代码比第二个代码好。
B
个实例将movedsince C++11 / 复制 pre-C ++ 11 到向量中,因此它们不会脱离循环后的范围 - 仅在向量超出范围之后。
如果您想获得绝对最佳的性能,请执行以下操作:
void foo() {
std::vector<B> bar;
bar.reserve(7);
for (int i = 0; i < 7; i++)
bar.emplace_back(i, i, i);
bar[3].do_stuff();
}
这将保证只有一次重新分配,并且根据Marc Glisse的评论,元素直接在向量内部构建(而不是在那里移动或复制它们)。
答案 2 :(得分:4)
不,std::vector
取得其成员的所有权,因此原始代码可以正常工作。
答案 3 :(得分:3)
std::vector
复制提供给它的对象(例如push_back()
)并保留它们直到向量本身被销毁。
因此,只要B(B(const B&)
)的复制构造函数正确实现,第一个代码就完全可以了。