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

时间:2015-03-14 11:57:03

标签: 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;
}

返回不同的内存地址。由于不再需要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;
}

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

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;
}

我预计bar已超出范围且无法再引用,但这会编译并返回正确的值(MSVC ++ 2013)。

2 个答案:

答案 0 :(得分:3)

  

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

只需返回对象即可。 C ++有return value optimization which means the copy can be (and most often is) elided

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

....

big_object big = get_object(); // big gets built in-place

如果您查看函数内bo的地址和外部的big,您可能会看到相同的地址(尽管RVO是可以发生的优化,但 ,因此还有其他因素会影响您是否看到相同的地址。使用最近的g ++和clang ++,我得到大小为{{1}的对象的相同地址} bytes,但不是大小8。)例如,这会在clang ++ 3.5上产生相同的地址:

4

答案 1 :(得分:0)

如果您的编译器遵循C ++标准,则不需要使用奇怪的代码:实际上允许编译器(根据标准)优化函数值的返回,省略任何副本(只是Google“c ++返回值)优化”)。 这样,您甚至可以按值返回堆栈中的大型结构,而不必担心。

编辑:答案已更正,多亏了juanchopanza。