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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> const reference to the temporary object 
V
    Опции темы
vinter
Дата 17.3.2009, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



после прочтения этой статтьи у меня появился резонный вопрос: WTF? Кто, что думает по поводу подобного?


--------------------
Мой блог
PM MAIL WWW   Вверх
InvalidProperty
Дата 17.3.2009, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 9



В чем заключается вопрос? Подобные конструкции языка не являются ошибочными. Если же вопрос заключается в целесообразности такого использования, так я лучше приведу две цитаты:
"Си остр, как бритва, с помощью него можно создать как красивую статую, так и кровавое месиво" (Керниган)

"C - если вы захотите выстрелить себе в ногу, то сделаете без проблем.
C++ - вы можете выстрелить себе в ногу, даже если не хотели этого." (автор неизвестен)


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
vinter
Дата 17.3.2009, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(InvalidProperty @  17.3.2009,  15:16 Найти цитируемый пост)
 Подобные конструкции языка не являются ошибочными

почему не являются? Где это написано? Я не понимаю на каком основании продлевается время жизни объекта.


--------------------
Мой блог
PM MAIL WWW   Вверх
InvalidProperty
Дата 17.3.2009, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 9



рассматривая объект класса string, можно совершенно определенно сказать, что время жизни продлевается на том основании, что объект будет существовать до тех пор, пока на него не закончатся ссылки. Ссылки всего 2. После выхода из функции - одна. Так почему же объект должен удаляться?


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
vinter
Дата 17.3.2009, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(InvalidProperty @  17.3.2009,  15:42 Найти цитируемый пост)
что время жизни продлевается на том основании, что объект будет существовать до тех пор, пока на него не закончатся ссылки

не забываем, что это С++ и garbage collector здесь отсутсвует, а значит понятия "пока на него не закончатся ссылки" в С++ несуществует, если мы не используем smart pointers(но это совершенно другая тема, здесь не об этом)


--------------------
Мой блог
PM MAIL WWW   Вверх
InvalidProperty
Дата 17.3.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 9



не забываем, что класс string построен именно таким образом, что его объект не уничтожится, пока на него не закончатся внутренние ссылки. Объект класса string не копируется при присваивании, увеличивается внутренний счетчик ссылок. Копирование происходит только при изменении объекта. При удалении счетчик ссылок уменьшается. Garbage collector тут совсем ни при чем.
В данном же случае, используется ссылка на функцию, возвращающую значение. Значение живет на момент выхода из функции. Тут мы для него заводим новую ссылку. Ссылка - это алиас переменной, альтернативное имя. Так почему же объект должен быть уничтоженным, если переменная еще жива в текущем контексте (я говорю про тот момент, когда заводится ссылка const string& s = f();)? 


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
Lazin
Дата 17.3.2009, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Тут подсчет ссылок не используется, просто, компилятор располагает объект в стеке так, что-бы его время жизни было больше чем время жизни ссылок на него. Напомню, что это работает только для объектов в стеке.
PM MAIL Skype GTalk   Вверх
xvr
Дата 17.3.2009, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(vinter @ 17.3.2009,  14:38)
Цитата(InvalidProperty @  17.3.2009,  15:16 Найти цитируемый пост)
 Подобные конструкции языка не являются ошибочными

почему не являются? Где это написано?

Это написано в стандарте
12.2 Temporary objects
Цитата

5 The second context is when a 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

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


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


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

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



Цитата(InvalidProperty @  17.3.2009,  14:11 Найти цитируемый пост)
не забываем, что класс string построен именно таким образом, что его объект не уничтожится, пока на него не закончатся внутренние ссылки. 

Вы про std::string  ? она не обладает подсчетом ссылок и не стоит путать с QString и wxString, которые построены по технологии COW (copy on write)

Цитата(InvalidProperty @  17.3.2009,  14:11 Найти цитируемый пост)
я говорю про тот момент, когда заводится ссылка const string& s = f();)

тут речь идет о случае const int & ri = 13;





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


Опытный
**


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

Репутация: нет
Всего: 9



самым верным способом будет проверить дизассемблированный текст и, как мне кажется, Lazin говорит правду, ибо компилятор, как только дойдет до строки
Код

const string& s = f();

положит на стек объект, который будет определен возвращаемым функцией значением. Это будет кадр стека внешней функции, поэтому и время жизни - время жизни внешней функции


--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
mes
Дата 17.3.2009, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(xvr @  17.3.2009,  14:26 Найти цитируемый пост)
Это написано в стандарте

цитата то обрезана  smile 

Цитата

 is  bound  persists  for the lifetime of the reference or until the end of the scope
  in which the temporary is created, whichever comes first.


только мне кажется эта цитата не объясняет.. ведь в примере по сылке временный объект создается внутри функции и соответсвенно время жизни должно определяться 
scope`ом той функции. 

Это сообщение отредактировал(а) mes - 17.3.2009, 15:34


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



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



время "жизни" объекта в стеке заканчивается тогда, когда выполняется mov esp,ebp/ret 
данные в стеке непосредственно при этом никуда не пропадают, но при выполнении последующего кода они могут пропасть

PM MAIL ICQ   Вверх
InvalidProperty
Дата 17.3.2009, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 9



Цитата(mes @  17.3.2009,  15:27 Найти цитируемый пост)
Вы про std::string  ? она не обладает подсчетом ссылок и не стоит путать с QString и wxString, которые построены по технологии COW (copy on write)


wiki (string) - обладает. Во всяком случае, я не встречался с примерами, когда не обладает.
Цитата

Although GNU and Dinkumware C++ libraries use reference counting and copy-on-write techniques to avoid unnecessary copying, other implementations might not.


Цитата(mes @  17.3.2009,  15:27 Найти цитируемый пост)
тут речь идет о случае const int & ri = 13

это вообще откуда взялось??? smile 




--------------------
dd if=$0 of=$0 bs=1 count=76 seek=`du -b $0 | awk {'print $1'}` 2>/dev/null
dd if=$0 of=$0 bs=1 count=67 conv=notrunc oflag=append 2>/dev/null
echo $0 >> $0
PM MAIL ICQ Jabber   Вверх
vinter
Дата 17.3.2009, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



xvr, спасибо. Этого я и ждал(сам не нашел :( ). Очередной идиотизм языка..

Добавлено через 2 минуты и 33 секунды
Цитата

The second context is when a 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 except as specified below. A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2)
persists until the constructor exits. A temporary bound to a reference parameter in a function call (5.2.2) persists until
the completion of the full expression containing the call. A temporary bound to the returned value in a function return
statement (6.6.3) persists until the function exits. The destruction of a temporary whose lifetime is not extended by
being bound to a reference is sequenced before the destruction of every temporary which is constructed earlier in the
same full-expression. If the lifetime of two or more temporaries to which references are bound ends at the same point,
these temporaries are destroyed at that point in the reverse order of the completion of their construction. In addition, the
destruction of temporaries bound to references shall take into account the ordering of destruction of objects with static
or automatic storage duration (3.7.1, 3.7.2); that is, if obj1 is an object with the same storage duration as the temporary
and created before the temporary is created the temporary shall be destroyed before obj1 is destroyed; if obj2 is an
object with the same storage duration as the temporary and created after the temporary is created the temporary shall be
destroyed after obj2 is destroyed. [ Example:
Код

struct S {
S();
S(int);
friend S operator+(const S&, const S&);
~S();
};
S obj1;
const S& cr = S(16)+S(23);
S 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. —end example ]


Добавлено через 3 минуты и 29 секунд
Цитата(InvalidProperty @  17.3.2009,  16:38 Найти цитируемый пост)
other implementations might not.

это тебе ни о чем не говорит?


--------------------
Мой блог
PM MAIL WWW   Вверх
Lazin
Дата 17.3.2009, 15:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(mes @  17.3.2009,  15:31 Найти цитируемый пост)
только мне кажется эта цитата не объясняет.. ведь в примере по сылке временный объект создается внутри функции и соответсвенно время жизни должно определяться 
scope`ом той функции

нед, там создается временный объект в том-же scop-e что и ссылка на него, объект возвращается по значению

Код

string get()
{
    return string("hello");
}

{
    const string& ref = get();
    ...using ref...
}

как в примере, так делать можно
Код

const string& get()
{
    return string("hello");//wrong
}

...
{
    const string& ref = get();
}

возвращать из ф-ии даже константную ссылку на временный объект нельзя

Добавлено через 2 минуты и 35 секунд
это не идиотизм языка, это нужно для того, что-бы лишний раз не копировать объект передаваемый по значению
PM MAIL Skype GTalk   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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