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

标签 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)。

最佳答案

It doesn't really matter for a simple integer but for larger Objects, what would be the preferred way to make sure the returned object does not get copied in memory?

只返回对象。 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++,我得到相同大小的对象的地址8 字节,但不是大小 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;
}

关于c++ - 返回局部变量而不复制它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29048635/

相关文章:

c++ - 为什么未按顺序从 CMap 中检索元素

c++ - 在 C++ 中使用函数指针映射枚举键和值

c++ -/usr/bin/ld :/tmp/cc9zxSDP. o: undefined symbol 引用

c++如何初始化数组的const元素

c++ - 如何将数组推送到标准 vector 中

c++ - 如何用不同数量的默认参数包装一个函数,使其只有一个参数?

c++ - 为什么 std 智能指针类型析构函数不继承指向对象的 noexcept dtor 状态

c++ - 用于创建/注册虚拟存储设备的 IOKit 驱动程序

c++ - 如何在 mpl::list 中声明一个 boost 递归变体?

c++ - 我可以在初始化数组时避免 c++11 移动吗?