返回局部变量而不复制它们

Bos*_*ash 5 c++

我是 C++ 的新手,想知道是否有办法在函数中创建对象,然后返回该对象而不必将其复制到内存中。我知道原始本地对象超出范围,但我希望编译器可以优化它,使对象的副本只重用相同的内存地址。

int foo()
{
    int bar = 5;
    std::cout << &bar << std::endl;

    return bar;
}

int main()
{
    char a;
    auto b = foo();
    std::cout << &b << std::endl;
    std::cin >> a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这将返回不同的内存地址。既然bar的地址不再需要,而且b的大小总是一样的,那么有什么理由不能只使用相同的地址并省去复制的步骤呢?


对于一个简单的整数并不重要,但对于更大的对象,确保返回的对象不会被复制到内存中的首选方法是什么?

以下是一个好方法吗?

int & foo(int & bar)
{
    std::cout << &bar << std::endl;
    // do things with bar
    return bar;
}

int main()
{
    char a;
    auto bar = 5;
    auto & b = foo(bar);
    std::cout << &b << std::endl;
    std::cin >> a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

作为一个附带问题,为什么以下事情有效:

int & foo()
{
    int bar = 5;
    std::cout << &bar << std::endl;

    return bar;
}

int main()
{
    char a;
    auto & b = foo();
    std::cout << &b << " " << b << std::endl;
    std::cin >> a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我希望 bar 超出范围并且不能再被引用,但是这会编译并返回正确的值(MSVC++ 2013)。

jua*_*nza 4

对于简单的整数来说并不重要,但对于较大的对象来说,确保返回的对象不会在内存中复制的首选方法是什么?

只需返回对象即可。C++ 具有返回值优化,这意味着可以(并且最常见的是)省略副本

big_object get_object()
{
    big_object bo;
    ....
    return bo;
}

....

big_object big = get_object(); // big gets built in-place
Run Code Online (Sandbox Code Playgroud)

如果您查看bo函数内部和big外部的地址,您会期望看到相同的地址(尽管 RVO 是一种可能发生的优化,但并非必须如此,因此还有其他因素可能会影响您是否看到相同的地址。使用最近的 g++ 和 clang++,我对于 size bytes 的对象获得相同的地址8,但对于 size 则不然4。)例如,这会在 clang++ 3.5 上产生相同的地址:

#include <iostream>

struct foo { int i[2]; };

foo make_foo()
{
  foo f;
  std::cout << &f << std::endl;
  return f;
}

int main()
{
  foo f = make_foo();
  std::cout << &f << std::endl;
}
Run Code Online (Sandbox Code Playgroud)