C++ 向量初始化:使用这种语法到底发生了啥? [关闭]

Posted

技术标签:

【中文标题】C++ 向量初始化:使用这种语法到底发生了啥? [关闭]【英文标题】:C++ vector initialization: what is actually going on using this syntax? [closed]C++ 向量初始化:使用这种语法到底发生了什么? [关闭] 【发布时间】:2016-08-25 17:16:07 【问题描述】:

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

考虑一个初始化向量的函数

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”被创建时到底发生了什么。这似乎至少是不必要的内存重复。

【问题讨论】:

data &lt;&lt; (float) i; 甚至不应该编译。你有 &lt;&lt; 重载来做一些特别的事情吗? Doesn't compile 都解释的很好here 【参考方案1】:

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

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

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

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

【讨论】:

以上是关于C++ 向量初始化:使用这种语法到底发生了啥? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C++ 这里到底发生了啥? [关闭]

使用带有引用的对象向量的 C++ 语法

调试 JSF 生命周期——每个阶段到底发生了啥

指针到底存储了啥? (C++)

索引操作到底发生了啥?

android“强制关闭”内存到底发生了啥