我有以下方法,它通过值返回本地声明的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和人类有相同的地址,那么返回值和返回参考值之间的区别在哪里?
答案 0 :(得分:6)
调用者没有收到对被调用者本地变量的引用,而是编译器将对调用者变量的引用隐藏到被调用者中!
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
的地址,就像你看到的一样。我相信这是返回值优化的定义。