是否不可能在没有指针的循环中构造实例?

pep*_*dip 7 c++

这段代码会爆炸,对吗?一旦循环退出,原始实例将与其所有内部成员一起死亡,因此如果它们不是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();
}
Run Code Online (Sandbox Code Playgroud)

那么,有没有办法在不使用指针的情况下做到这一点?或者你必须这样做:

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];
}
Run Code Online (Sandbox Code Playgroud)

650*_*502 12

第一个代码示例有效.

std::vector将传递它们的对象的副本push_back(或者如果您正在推动临时的话,将使用C++ 11 它们移动到位)并且只要向量本身处于活动状态,它将使所有实例保持活动状态.

退出函数时会发生破坏,而不是退出循环时.

  • "会复制",或__move__.(在这种情况下,如果它被编译为> = C++ 11,那将是一个移动.) (2认同)

eml*_*lai 7

第一个代码比第二个代码好.

B实例将被移动,因为C++ 11/复制预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();
}
Run Code Online (Sandbox Code Playgroud)

这将保证只有一次重新分配,并且根据Marc Glisse的评论,元素直接构造在向量内(而不是在那里移动或复制它们).

  • 如果它是C++ 11,它应该使用emplace_back并且完全避免移动. (3认同)
  • 这就是我上面写的!!! 您可以使用emplace_back直接在向量中构建这些实例(显然,您首先调用reserve(...)以避免重新分配,这会导致移动). (2认同)