Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Возврат из функции: по ссылке, по указателю, Не понимаю механику 
V
    Опции темы
Gunslinger
Дата 16.12.2009, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 842
Регистрация: 30.12.2006
Где: Астрахань

Репутация: 1
Всего: 3



Цитата(xvr @  15.12.2009,  12:09 Найти цитируемый пост)
Есть еще одна тонкость в применении ссылок:
Код

SomeObject func();
SomeObject& ref=func();

В последней строке будет созданна ссылка на объект, возвращенный функцией func. Время жизни этого объекта будет расширенно до времени жизни ссылочной переменной ref
Ни создания отдельного объекта, ни copy конструктора вызванно не будет (как в случае SomeObject ref=func();


Цитата(xvr @  15.12.2009,  15:31 Найти цитируемый пост)
Цитата(mes @ 15.12.2009,  12:36)
Цитата(xvr @  15.12.2009,  11:09 Найти цитируемый пост)
SomeObject& ref=func();

Хотя некоторые компиляторы идут на встречу позволяя подобное, 
 но по правилам, насколько я знаю, временным объектом можно проинициалировать только константную ссылку.

Угу, это я как то пропустил . Посыпаю голову пеплом и исправляюсь smile :
Код

const SomeObject& ref=func();

в остальном все правильно


1. Ссылка и указатель на функцию значат, что функция создала переменную с результатом и на эту переменную возвратила адрес. Но локальные переменные после завершения работы функции удаляются. Или ссылки и указатели дают, если возвращающее значение создается в куче?
2. Не понятны выделенные строки - копировать не стал, чтобы пост не увеличивать.
PM MAIL   Вверх
xvr
Дата 16.12.2009, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата

Ссылка и указатель на функцию значат, что функция создала переменную с результатом и на эту переменную возвратила адрес. 
Если это про SomeObject func(); - то это прототип функции, возвращающей объект (а не ссылку на него)
Цитата

Но локальные переменные после завершения работы функции удаляются. 
Локальный - да, возвращаемый - нет.
Если в целом, то такое действо:
Код

SomeObject func()
{
 SomeObject rv;
 ...
 return rv;
}

SomeObject my_obj=func();
реализуется так (это без учета возможных оптимизаций) - псевдокод:
Код

my_obj.SomeObject() -- Default constructor
call func()
 rv.SomeObject() -- Default constructor
 ...
 return &rv;
my_obj.operator = (rv);
rv.~SomeObject()


Цитата

Не понятны выделенные строки
В стандарте есть специальная трактовка конструкции
Код

const SomeObject& ref=func();
Глава 12.2 (Temporary objects)
Цитата

5. reference is bound to a temporary. The temporary to which the reference is bound or
the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the
reference

Код

class C {
/ / ...
public :
C();
C(int );
friend C operator +( const C&, const C&);
~C();
};

C obj1 ;
const C& cr = C (16)+ C (23);
C obj2 ;

the expression C(16)+C(23) creates three temporaries. A first temporary T1 to hold the result of the expression C(16),
a second temporary T2 to hold the result of the expression C(23), and a third temporary T3 to hold the result of the
addition of these two expressions. The temporary T3 is then bound to the reference cr. It is unspecified whether T1 or
T2 is created first. On an implementation where T1 is created before T2, it is guaranteed that T2 is destroyed before T1.
The temporaries T1 and T2 are bound to the reference parameters of operator+; these temporaries are destroyed at the
end of the full expression containing the call to operator+. The temporary T3 bound to the reference cr is destroyed
at the end of cr’s lifetime, that is, at the end of the program. In addition, the order in which T3 is destroyed takes into
account the destruction order of other objects with static storage duration. That is, because obj1 is constructed before
T3, and T3 is constructed before obj2, it is guaranteed that obj2 is destroyed before T3, and that T3 is destroyed before
obj1.


PM MAIL   Вверх
Gunslinger
Дата 17.12.2009, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 842
Регистрация: 30.12.2006
Где: Астрахань

Репутация: 1
Всего: 3



Цитата(xvr @  16.12.2009,  12:52 Найти цитируемый пост)
Локальный - да, возвращаемый - нет.

Получается, даже стековый объект не уничтожается и поэтому на него можно возвращать ссылки и указатели?

Цитата(xvr @  16.12.2009,  12:52 Найти цитируемый пост)
В стандарте есть специальная трактовка конструкции
Код

const SomeObject& ref=func();


С переводом туго, пытаюсь въехать, как понял. ref - ссылка на результат функции и она объявлена константой, т.е. менять ее значение нельзя. Это как-то связано с тем, что значение на самом деле находится в функции? Например, компилятор запрещает писать в такие участки памяти?



Это сообщение отредактировал(а) Gunslinger - 17.12.2009, 10:09
PM MAIL   Вверх
xvr
Дата 17.12.2009, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Gunslinger @ 17.12.2009,  10:05)
Цитата(xvr @  16.12.2009,  12:52 Найти цитируемый пост)
Локальный - да, возвращаемый - нет.

Получается, даже стековый объект не уничтожается и поэтому на него можно возвращать ссылки и указатели?


Нет. Это случай, когда возвращается САМ объект (by value), а не ссылка или указатель на него. В таком случае происходит копирование возвращаемого объекта из стека вызванной функции в стек вызывающей (при выполнении оператора return в вызванной функции)

Цитата

Цитата(xvr @  16.12.2009,  12:52 Найти цитируемый пост)
В стандарте есть специальная трактовка конструкции
Код

const SomeObject& ref=func();


С переводом туго, пытаюсь въехать, как понял. ref - ссылка на результат функции и она объявлена константой, т.е. менять ее значение нельзя. Это как-то связано с тем, что значение на самом деле находится в функции? Например, компилятор запрещает писать в такие участки памяти?
Писать туда действительно нельзя (хотя это и условность - const_cast может эту константность перебить  smile )
Основной цимус тут в том, что такая конструкция позволяет избежать копирования объекта (за счет усложнения компилятора  smile )

PM MAIL   Вверх
Gunslinger
Дата 17.12.2009, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 842
Регистрация: 30.12.2006
Где: Астрахань

Репутация: 1
Всего: 3



Цитата(xvr @  17.12.2009,  11:33 Найти цитируемый пост)
Это случай, когда возвращается САМ объект (by value), а не ссылка или указатель на него. В таком случае происходит копирование возвращаемого объекта из стека вызванной функции в стек вызывающей (при выполнении оператора return в вызванной функции)

и
Цитата(xvr @  17.12.2009,  11:33 Найти цитируемый пост)
такая конструкция позволяет избежать копирования объекта

У меня не вяжется. Сейчас моя логика такая: 
1. Автоматические переменные после выхода из блока уничтожаются
2. Ссылка - всего лишь псевдоним и вместо нее компилятор подставляет автоматическую переменную из блока функции
3. Указатель - адрес. Адресуется опять же  на переменную в функции.
Отсюда выводы такие: 
1. Возврат по значению: либо объект, либо выражение (temporary T3 из примера стандарта) копируется в переменную во внешней программе, которой присвоен
2. Возврат по ссылке\указателю: работа с переменной\temporary T3 функции


Это сообщение отредактировал(а) Gunslinger - 17.12.2009, 19:29
PM MAIL   Вверх
xvr
Дата 17.12.2009, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Gunslinger @ 17.12.2009,  19:24)
У меня не вяжется. Сейчас моя логика такая: 
1. Автоматические переменные после выхода из блока уничтожаются
2. Ссылка - всего лишь псевдоним и вместо нее компилятор подставляет автоматическую переменную из блока функции
3. Указатель - адрес. Адресуется опять же  на переменную в функции.

Это так, но совершенно непонятно, какое это имеет отношение к рассматриваемому примеру - там нет возврата ПО ССЫЛКЕ или УКАЗАТЕЛЯ.
Цитата

Отсюда выводы такие: 
1. Возврат по значению: либо объект, либо выражение (temporary T3 из примера стандарта) копируется в переменную во внешней программе, которой присвоен
2. Возврат по ссылке\указателю: работа с переменной\temporary T3 функции
Выводы правильные, но не полные - рассматриваемый пример не попадает под эти 2 альтернативы. 3я альтернатива возникает при особом способе использования вызова функции, возвращающей объект by-value. Если способ вызова будет другой (например инициализация объекта возвращаемым значением), то и вывод тоже будет другой (конкретно будет 1й вариант)

PM MAIL   Вверх
Gunslinger
Дата 18.12.2009, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 842
Регистрация: 30.12.2006
Где: Астрахань

Репутация: 1
Всего: 3



Цитата(xvr @  17.12.2009,  19:56 Найти цитируемый пост)
при особом способе использования вызова функции

т.е. это чисто логическая штука? Ума не приложу, что еще можно делать с памятью на физическом уровне, кроме как копировать\обрабатывать содержимое ячейки и обращаться к ней по адресу..
PM MAIL   Вверх
xvr
Дата 18.12.2009, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Gunslinger @ 18.12.2009,  09:18)
Цитата(xvr @  17.12.2009,  19:56 Найти цитируемый пост)
при особом способе использования вызова функции

т.е. это чисто логическая штука? 

Весь компилятор 'чисто логическая штука' Процессор ничего не знает о том, что такое 'объект', 'класс', 'exception' и т.д.
Цитата

Ума не приложу, что еще можно делать с памятью на физическом уровне, кроме как копировать\обрабатывать содержимое ячейки и обращаться к ней по адресу..
Собственно ничего. Тебя же не удивляет, что имея в распоряжении всего 32 буквы можно написать 'Войну и мир'?

PM MAIL   Вверх
mes
Дата 18.12.2009, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Gunslinger @  18.12.2009,  08:18 Найти цитируемый пост)
это чисто логическая штука? 

Имхо, В cpp (как в любом ЯВУ) практически все конструкции надо понимать как "логическую штуку", за исключением когда специально расматривается  конструкция в условиях реализации конкретного компилятора.

Цитата(Gunslinger @  17.12.2009,  18:24 Найти цитируемый пост)
2. Ссылка - всего лишь псевдоним 

увы не всего лишь. Это утверждение справедливо лишь ссылки на полноценный объект. Есть еще правило, приведенное цитатой xvr
и на которое Вы не обратили должного внимания :
Цитата(xvr @  16.12.2009,  11:52 Найти цитируемый пост)
5. reference is bound to a temporary. The temporary to which the reference is bound or
the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the
reference


 smile

Добавлено через 1 минуту и 56 секунд
 smile 
Цитата(xvr @  18.12.2009,  09:04 Найти цитируемый пост)
32 буквы 

32 ?!  smile 

Это сообщение отредактировал(а) mes - 18.12.2009, 10:26


--------------------
PM MAIL WWW   Вверх
Gunslinger
Дата 18.12.2009, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 842
Регистрация: 30.12.2006
Где: Астрахань

Репутация: 1
Всего: 3



Цитата(mes @  18.12.2009,  10:25 Найти цитируемый пост)
Это утверждение справедливо лишь ссылки на полноценный объект. Есть еще правило, приведенное цитатой xvr
и на которое Вы не обратили должного внимания :

Там по временные переменные, ссылки и время жизни - а все вместе скомпоновать в осмысленное предложение я не смог. Вот и не понял смысл 3й альтернативы.


Это сообщение отредактировал(а) Gunslinger - 18.12.2009, 13:15
PM MAIL   Вверх
mes
Дата 18.12.2009, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Gunslinger @  18.12.2009,  12:14 Найти цитируемый пост)
. Вот и не понял смысл 3й альтернативы.

В общем там говорится , что если временный объект "пристыковать" к ссылке, то он сохраняется (удлиняет жизнь) на все время жизни ссылки.

 smile 

Это сообщение отредактировал(а) mes - 18.12.2009, 13:28


--------------------
PM MAIL WWW   Вверх
Gunslinger
Дата 18.12.2009, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 842
Регистрация: 30.12.2006
Где: Астрахань

Репутация: 1
Всего: 3



Цитата(mes @  18.12.2009,  13:27 Найти цитируемый пост)
В общем там говорится , что если временный объект "пристыковать" к ссылке, то он сохраняется (удлиняет жизнь) на все время жизни ссылки.

Спасибо, но чем тогда эта инфа из стандарта отличается от тоо, что я писал выше:
Цитата(Gunslinger @  17.12.2009,  19:24 Найти цитируемый пост)
2. Возврат по ссылке\указателю: работа с переменной\temporary T3 функции
?
Судя по ответу xvr, мой ответ не подходил для данного случая. Мне интересно, как правильно - чтобы знать нюансы работы с получаемыми подобным образом (*, &) результатами.


Это сообщение отредактировал(а) Gunslinger - 18.12.2009, 14:13
PM MAIL   Вверх
mes
Дата 18.12.2009, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Gunslinger @  18.12.2009,  13:09 Найти цитируемый пост)
отличается от тоо, что я писал выше: 2. Возврат по ссылке\указателю:

1. в примере который мы разбираем нет никакого возврата по ссылке/указателю
2. можно бы продолжать, но пункта 1. более чем достаточно, хотя в Вашей фразе и помимо него много неясностей..





--------------------
PM MAIL WWW   Вверх
Gunslinger
Дата 18.12.2009, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 842
Регистрация: 30.12.2006
Где: Астрахань

Репутация: 1
Всего: 3



 
Цитата(mes @  18.12.2009,  14:58 Найти цитируемый пост)
хотя в Вашей фразе и помимо него много неясностей..

что именно - разъясню. Может тогда станет ясно, почему я вас обоих не понимаю.
PM MAIL   Вверх
mes
Дата 18.12.2009, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Gunslinger @  17.12.2009,  18:24 Найти цитируемый пост)
1. Автоматические переменные после выхода из блока уничтожаются

А когда уничтожаются временные объекты ?

Цитата(Gunslinger @  17.12.2009,  18:24 Найти цитируемый пост)
2. Ссылка - всего лишь псевдоним

который имеет некоторые (неочевидные) особенности/правила связанные с его использованием

Цитата(Gunslinger @  17.12.2009,  18:24 Найти цитируемый пост)
из блока функции

блок функции  и функциональный блок - несколько разные понятия

Цитата(Gunslinger @  17.12.2009,  18:24 Найти цитируемый пост)
3. Указатель - адрес.

Нет. У адреса можно разве взять его адрес ?

Цитата(Gunslinger @  17.12.2009,  18:24 Найти цитируемый пост)
 Адресуется опять же  на переменную в функции.

да ?!
 
Цитата(Gunslinger @  17.12.2009,  18:24 Найти цитируемый пост)
Отсюда выводы такие: 

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

Цитата(Gunslinger @  18.12.2009,  14:18 Найти цитируемый пост)
что именно - разъясню. 

оба Ваших вывода smile и не только.

Цитата(Gunslinger @  18.12.2009,  14:18 Найти цитируемый пост)
Может тогда станет ясно, почему я вас обоих не понимаю. 

Ну это я могу объяснить.. Потому что вместо того чтоб принять абстракции и разбирать их, Вы пытаетесь найти во что превращаются абстрактные инструменты в конечном исполнении, упустив при этом большую часть работы.
 То есть вместо разбора того, как рисовать худ. инструментами, и какими особенностями обладает каждая из них, например чем кисточка отличается от каранда и от губки,
Вы приводите все к одному выводу, они оставляют след краской. Может для ксерокопии картины и достаточно изучить каким цветом выражен каждый пиксель,
но для художества, надо понимать, как можно получить нужный эффект, не заботясь о каждом пикселе.

Это сообщение отредактировал(а) mes - 18.12.2009, 16:03


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1632 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.