C ++向量初始化:使用这种语法实际发生了什么?

时间:2016-08-25 17:16:08

标签: c++ memory vector

我在另一个网站上看到了一些代码,我想知道发生了什么的微妙之处。

考虑初始化向量的函数

vector<float>  initvec  ( int nx,  int ny,  int nz ) {
  vector<float> data;
  for (int i = 0; i < nx * ny *nz; ++i){ // assign data elements with sequential values from 0 to nx*ny*nz-1}
  return data;
}

然后再

void other( int nx, in ny, int nz ) {
  …
  vector<float> A( initvec  ( nx, ny, nz ) );
  …
}

我不清楚创建向量“A”时的字面意思。它似乎至少像是不必要的重复记忆。

1 个答案:

答案 0 :(得分:1)

我想你想知道为什么我们不简单地将initvec函数的结果分配给A变量而不是调用构造函数。

事实上,它在C ++中并不重要。你认为,有一个不必要的副本正在进行但事实并非如此。由于vector实际上是一个类,因此C#或Java等语言中的行为只是在分配给A变量时复制返回的引用。

在C ++中,我们有移动语义 - 这意味着内存将在这种情况下重用。在initvec中,data已在堆栈上分配,然后沿return语句复制。然后,vector类的移动构造函数重用了这个内存。

另一方面,我们无法返回data的引用,因为它是在堆栈上分配的(避免在返回时分配内存)。一旦我们将函数地址留给局部变量就不再有效了。但是,我们可以使用new operator或使用智能指针在堆上分配此向量并将其返回。这会模仿我之前提到的语言的行为。请记住,在前一种情况下,您信任initvec函数的用户来释放已分配的内存。