2015-05-29 4 views
3

Тема в значительной степени находится в названии вопроса. Я видел это в Meyrses книге «Эффективное использование C++»:C++ возвращает объекты по значению

тот факт, что C++ возвращает объекты по значению

Что это значит и как стандарт C++ поддерживает это сообщение? Для instanance, говорят, что у нас есть что-то вроде этого:

int foo() 
{ 
    int a = 1; 
    return a; 
} 

Это довольно ясно, эта фраза означает, что мы возвращает копию значения, хранимого в локальной переменной. Но учтите следующее:

int& foo() 
{ 
    int a = 1; 
    return a; 
} 

Компилятор должен предупредить нас о возврате ссылки на локальную переменную. Как этот «возврат по значению стоимости» применяется к этому примеру?

+0

Значение, возвращаемое во втором примере, является указателем на определенный адрес памяти. Тот факт, что адрес просто оказывается временным местом в стеке, является случайным. (И да, хороший компилятор выдает предупреждение здесь) – shuttle87

+5

@ shuttle87: Нет, это не так. Это ссылка, а не указатель. –

+0

@ shuttle87 Я не уверен, можем ли мы поговорить о том, что происходит во втором примере, потому что я думаю, что это UB. –

ответ

6

Meyers является правильным в основном, хотя вы должны принять эту формулировку с щепоткой соли при работе со ссылками. На определенном уровне абстракции здесь вы передаете ссылку «по значению».

Но то, что он действительно пытается сказать, заключается в том, что, кроме того, C++ передает значение по умолчанию и что это контрастирует с такими языками, как Java, в которых объекты всегда забрасываются ссылочной семантикой.

Фактически, один может утверждать, что этот отрывок не применяется к вашему коду вообще, потому что ссылка не является «объектом».

+0

Итак, я получил UB во втором примере, справа ? –

+0

@ St.Antario Right –

+0

Это разумно спросить, почему ... Я предполагаю, что переменные с автоматическим временем хранения будут стерты после возврата значения. Таким образом, у нас есть неопределенное значение по ссылке, возвращаемой функцией. Где UB? –

0

Возврат по ссылке даст вам сообщение об ошибке, когда вы передаете ссылку переменной на другую функцию (функцию, которая вызвала функцию foo), которая выходит за пределы этой локальной переменной (переменная a).

+1

Не будет «дать вам ошибку». Кроме того, вы не ответили на вопрос. –

+0

ну его предупреждение .. не ошибка. (Извините за ошибку). Хотя локальная переменная недоступна для родительской функции, но ее ценность доступна. –

2

Когда в книге говорится, что «C++ возвращает объекты по значению», это объясняет, что происходит, когда вы используете «простое» имя класса в качестве возвращаемого типа без дополнительных «украшений», таких как амперсанды или звездочки, например.

struct MyType { 
    ... // Some members go here 
}; 
MyType foo() { 
    ... 
} 

В приведенном выше примере foo() возвращает объект по значению.

Эта цитата не должна предполагать, что на C++ отсутствуют другие способы возврата данных из функции: поскольку вы можете легко построить функцию, возвращающую ссылку или указатель.

Обратите внимание, что возврат объекта по указателю или по ссылке создает неопределенное поведение только при возврате указателя или ссылки на локальный объект. Доступ к объекту за время его жизни всегда вызывает неопределенное поведение. Возвращение локального по ссылке или указателем является, пожалуй, самой распространенной ошибкой, которая вызывает это неопределенное поведение.

Смежные вопросы