【发布时间】:2015-11-18 13:56:26
【问题描述】:
下面的代码工作正常,据我所知,每次调用函数时,都会创建一个局部变量(即向量),并且所有权将在第一次调用时在右值引用和 const 引用中转移(如果我删除它甚至不会编译)在第二次调用。结果,当函数终止时,局部变量实际上并没有死,而是当 main 中的引用超出范围时(即在main() 的末尾),我认为 !
#include <iostream>
#include <vector>
std::vector<int> get_v(void)
{
std::vector<int> v{1,2,3};
return v;
}
int main() {
std::vector<int> &&rval_ref = get_v();
for(unsigned int i = 0; i < rval_ref.size(); ++i)
std::cout << rval_ref[i] << "\n";
const std::vector<int> &con_ref = get_v();
for(unsigned int i = 0; i < con_ref.size(); ++i)
std::cout << con_ref[i] << "\n";
return 0;
}
输出:
gsamaras@pythagoras:~$ g++ -std=c++0x -Wall px.cpp
gsamaras@pythagoras:~$ ./a.out
1
2
3
1
2
3
但我认为局部变量在超出范围时会死掉,除非在它们之前有一个 static 关键字,或者它们已经被动态分配,甚至被复制。在这种情况下,向量不会被复制。也许我的 C 背景让我无法理解这里的概念。你能帮帮我吗?
作为旁注,第一种情况允许您修改向量,而第二种显然不会。猜猜第一个是 C++11 的特性,而第二个是传统的。
我刚刚用自定义类做了一个示例,不会调用复制构造函数,但它会像上面的示例一样工作!
【问题讨论】:
-
get_v按 value 而非 reference 返回。 -
那么,复制构造函数将被称为@CaptainObvlious?朋友告诉我不会!
-
副本可能会被忽略,也可能不会。取决于优化。无论哪种方式,您仍然按值返回,因此将创建属于调用者的向量的唯一实例。
-
@CaptainObvlious 这对我来说并不明显,抱歉!也检查我的编辑。我不明白这是怎么发生的。
-
您返回一个副本,该副本成为 临时(未命名)对象。你的
const&然后绑定到未命名的临时给它一个名字(从而延长它的生命)。
标签: c++ c++11 scope rvalue-reference rvalue