【问题标题】:Same address for variables which are returned by value按值返回的变量的地址相同
【发布时间】:2012-03-13 02:08:20
【问题描述】:

我有以下方法按值返回本地声明的对象:

Human Human::getLocalDeclaredHuman() {    
    Human human;
    std::cout << &human << std::endl;
    return human;
}

我称这个方法为:

Human a;
Human b = a.getLocalDeclaredHuman();
std::cout << &b << std::endl;
std::cout << b.getName() << std::endl;

这是正在运行的程序的输出:
0x22fe58
0x22fe58
约翰·多伊

所以在方法中声明为local的变量human与变量b的地址相同。我认为return-by-value 将创建对象的副本,并且对象 b 具有另一个地址,例如在本地声明的对象 human。

我的问题:
如果这里b和human地址相同,那么按值返回和按引用返回的区别在哪里?

【问题讨论】:

    标签: c++ methods reference


    【解决方案1】:

    Return Value Optimization.

    与其说是调用者收到了对被调用者局部变量的引用,不如说是编译器将调用者变量的引用偷偷带入了被调用者!

    getLocalDeclaredHuman.human 从未真正存在过。编译器能够优化它的存在并直接在 b 上完成所有工作。

    而且,直接回答您的问题,“按值返回和按引用返回之间的区别在哪里?”:在这种情况下,按值返回意味着单个对象的生命周期为 @ 987654325@。如果您要通过引用返回 human,则该单个对象将具有 human 的生命周期,即当 getLocalDeclaredHuman() 返回时它将被销毁。

    【讨论】:

    • 感谢您提供获取背景知识和精彩解释的链接!
    • 而且,为了额外的乐趣,考虑一下this program 的作用。
    • 呵呵,是的。 c 有另一个地址而不是 F2 中的人,因为编译器无法知道 i 将是什么条件。可能会创建一个具有新地址的新人类。 F1() 和 F2() 中的 i1 拥有相同的地址也很棘手,但是当 F1() 完成时,地址又是空闲的,所以 F2() 中的 i1 可以接受它
    【解决方案2】:

    这是因为你的编译器执行了return value optimization

    【讨论】:

      【解决方案3】:

      副本很可能被忽略到外部范围,因此唯一被调用的方法是默认的人工副本构造函数。看看这个question 了解更多信息。

      【讨论】:

        【解决方案4】:

        这是返回值优化。编译器知道您将要使用它做什么,因此已在将要分配的位置创建它,因此无需复制。

        【讨论】:

          【解决方案5】:

          也许编译器已经优化掉了局部变量,因此您可以在函数内部对b 进行操作。

          像这样:

          void Human::getLocalDeclaredHuman(Human& returnValue)
          {
            std::cout << &human << std::endl;
          }
          

          然后在b 上调用它,从而打印b 的地址,就像您看到的一样。我相信这就是返回值优化的定义。

          【讨论】:

            猜你喜欢
            • 2015-10-25
            • 2021-04-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-24
            • 2021-11-12
            相关资源
            最近更新 更多