在 C++ 中想要传入函数的参数不被复制,可以通过引用或者指针的方式传入。如果说想要返回的产生也不被复制呢?当然可以直接将返回的对象作为入参以引用或者指针的形式传入,实际上直接返回也可以不复制,在C++返回参数不被复制被称为 Copy Elision。
下面是一段简单的 C++ 程序,在 fun
函数厘米创建一个名为 x
的向量并将这个向量返回,然后在 main
函数中调用这个 fun
函数并将返回值赋给了 y
,第一反应这里的 y
应该是 x
的复制,也就是说在 main
中打印出来的 x
地址与 fun
中打印出来的 y
的地址应该是不一样的。
#include <vector>
#include <iostream>
std::vector<int> fun()
{
std::vector<int> x{1, 2, 3, 4};
std::cout << &x << std::endl;
return x;
}
int main()
{
std::vector<int> y = fun();
std::cout << &y << std::endl;
return 0;
}
但是在实际编译运行之后打印出来的结果如下,可以看到两个值是一样的
0x7ffee7ffb520
0x7ffee7ffb520
可以看到编译器在这自动优化过了,实际上 x
并没有复制一份。那么在什么情况下编译器会自动优化呢?**当返回结果上面没有判断的时候编译器会自动优化,如果存在判断编译器无法确定返回的是哪个的时候则不会优化。**可以看下面这个例子:
#include <vector>
#include <iostream>
std::vector<int> fun(int flag)
{
std::vector<int> x{1, 2, 3, 4};
std::cout << &x << std::endl;
if(flag)
{
return {3, 4, 2, 1};
}
return x;
}
int main()
{
std::vector<int> y = fun(false);
std::cout << &y << std::endl;
return 0;
}
在这里例子中只是加了一个 flag
参数来确定具体的返回值,传入的是 false
所以实际上程序的行为应该还是和第一个例子是一样的,但是此时打印的 x
和 y
的地址却不一样了,也就是说 vector<int>
发生了复制
参考