通过值返回的变量的相同地址

时间:2012-02-22 17:36:46

标签: c++ methods reference

我有以下方法,它通过值返回本地声明的Object:

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
John Doe

因此,在方法中声明为local的变量human与变量b具有相同的地址。我认为按值返回将创建对象的副本,并且对象b具有另一个地址,如在本地声明的对象人类。

我的问题:
如果这里b和人类有相同的地址,那么返回值和返回参考值之间的区别在哪里?

5 个答案:

答案 0 :(得分:6)

Return Value Optimization

调用者没有收到对被调用者本地变量的引用,而是编译器将对调用者变量的引用隐藏到被调用者中!

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

并且,直接回答你的问题,“按值返回和按引用返回的区别在哪里?”:在这种情况下,按值返回意味着单个对象的生命周期为{ {1}}。如果您通过引用返回b,则该单个对象的生命周期为human,即当human返回时它将被销毁。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

最有可能将副本省略到外部范围,以便调用的唯一方法是默认的人工副本构造函数。有关详细信息,请查看此question

答案 3 :(得分:0)

这是返回值优化。编译器知道你要用它做什么,所以在它被分配的位置创建了它,所以它不需要复制。

答案 4 :(得分:0)

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

像这样:

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

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