Тот же адрес для переменных, которые возвращаются по значению - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть следующий метод, который возвращает локальный объявленный объект по значению:

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
Джон Доу

Таким образом, переменная human, объявленная в методе local, имеет тот же адрес, что и переменная b. Я думал, что возврат по значению создаст копию объекта, и что у объекта b есть другой адрес, такой как объект human, который объявлен локально.

Мой вопрос:
Если здесь b и человек имеют один и тот же адрес, где разница между возвратом по значению и возвратом по ссылке?

Ответы [ 5 ]

6 голосов
/ 22 февраля 2012

Оптимизация возвращаемого значения .

Не так уж и много, что вызывающая сторона получила ссылку на локальную переменную вызываемого, а компилятор втиснул ссылку на переменную вызывающего вcallee!

getLocalDeclaredHuman.human никогда не существовало.Компилятор смог оптимизировать свое существование и выполнить всю свою работу непосредственно на b.

И, чтобы ответить на ваш вопрос напрямую, «где разница между возвратом по значению и возвратом по-refernce? ": в этом случае возврат по значению означает, что время жизни одного объекта b.Если бы вы вернули human по ссылке, этот единственный объект имел бы время жизни human, то есть он был бы уничтожен, когда getLocalDeclaredHuman() вернется.

1 голос
/ 22 февраля 2012

Скорее всего, копия удаляется за пределы области видимости, поэтому единственным вызываемым методом является конструктор человеческой копии по умолчанию.Посмотрите на этот вопрос для получения дополнительной информации.

1 голос
/ 22 февраля 2012

Это из-за оптимизации возвращаемого значения , выполненной вашим компилятором.

0 голосов
/ 22 февраля 2012

Возможно, компилятор оптимизировал локальную переменную, так что вместо этого вы работаете с b внутри функции.

Вот так:

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

тогда это вызывается b, и таким образом печатает адрес b точно так же, как вы видите. Я считаю, что это само определение оптимизации возвращаемого значения.

0 голосов
/ 22 февраля 2012

Это оптимизация возвращаемого значения. Компилятор знает, что вы собираетесь с ним делать, поэтому он создал его в том месте, куда он будет назначен, поэтому ему не нужно копировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...