Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
1

Ссылка на временный объект

11.08.2014, 03:24. Показов 3875. Ответов 24
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Наткнулся тут в гугле на одну интересную тему.
Как известно, данный код не соответствует стандарту, и не будет скомпилирован многими современными компиляторами:

C++
1
2
3
4
5
6
7
8
9
10
11
class A {
 
};
 
void f( A & ) {
   
}
 
int main() {
   f( A());
}
Но данный код компилируется, и вполне валиден:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A {
public:
   A &getThis() {
      return *this;
   }
};
 
void f( A & ) {
   
}
 
int main() {
   f( A().getThis());
}
Собственно, вопрос: почему он валиден?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.08.2014, 03:24
Ответы с готовыми решениями:

Не создаётся ссылка на временный объект
Что же делать? Код: #include <iostream> using namespace std; class BigClass { public:

Временный объект
Требуется создать при помощи конструктора временный объект. Затем присвоить временный объект...

Временный объект и конструктор копирования
Добрый день! Столкнулся c задачкой в тесте: class A{ public: A(){ ...

Возвращение const ссылки на временный объект
Добрый вечер, #include <iostream> using namespace std; struct Point { int _x; int _y; };

24
102 / 75 / 17
Регистрация: 23.07.2014
Сообщений: 877
Записей в блоге: 1
11.08.2014, 07:27 2
Toshkarik, в первом случае ссылка на временный объект, вы сами себе и ответили. Во-втором — функция возвращает ссылку на A, у функции такие же параметры. Почему это не должно скомпилироваться?
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,281
11.08.2014, 08:56 3
Цитата Сообщение от Toshkarik Посмотреть сообщение
Собственно, вопрос: почему он валиден?
Выражение A(); является rvalue. Причем неконстантным rvalue.
Метод getThis() возвращает lvalue.
Потому и валиден.
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
11.08.2014, 12:51  [ТС] 4
Почему компилируется понянто. Вопрос в другом, почему в этом случая временный объект живет до выхода из функции. Интересует не техническая часть, а почему это допустили. По сути мы схитрили и все же использовали временный объект для передали по ссылке в качестве параметра.
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
11.08.2014, 12:58 5
Toshkarik, временные объекты пока выполняется выражение.
Мб кто-нибудь приведет прямо ссылку на стандарт.
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
11.08.2014, 13:04 6
N3337 12.2/3

When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1, 12.8), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.
1
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
11.08.2014, 13:07  [ТС] 7
И про это в курсе, имеется в виду full-expression, ссылку на стандарт сейчас не дам, так как не помню. Может опять неправильно выразился. Попробуем наоборот: если возможен второй вариант, то почему запретили первый? Это же выглядит немного как "хак". Может быть, это одна из причин появления rvalue-reference в C++11...

Не по теме:

upd: А вот и стандарт :)

0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
11.08.2014, 13:19 8
Toshkarik, Как-то спрашивал про то, почему разрешена конверсия от rvalue к lvalue на SO, впринципе там ответили довольно полно: http://stackoverflow.com/quest... ual-studio
2
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,281
11.08.2014, 13:39 9
Цитата Сообщение от Toshkarik Посмотреть сообщение
почему запретили первый?
Это попытка запретить опасное использование. Если я не ошибаюсь, то предложение запрета первого варианта исходил от самого Страуструпа. А второй вариант запретить нельзя. Потому что, например, его не отличить вот от такого (пример утрирован):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A {
public:
   A(A * ref) : ref_(ref) {}
   A() : ref_(this) {}
   A &getThis() {
      return *ref_;
   }
   A * ref_;
};
 
void f( A & ) {
   
}
 
int main() {
   A a;
   f( A(&a).getThis());
}
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
11.08.2014, 14:02 10
Цитата Сообщение от Toshkarik Посмотреть сообщение
По сути мы схитрили
Именно в этом всё дело. Стандарт дает (старается дать) защиту от явных ошибок. Но когда программист хочет обойти защиту, он ее обойдет.
1
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
11.08.2014, 14:23  [ТС] 11
Так ведь непонятно в данном случае - от чего защищают?
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
11.08.2014, 14:27 12
Toshkarik, Не знаю насколько я буду прав, но первый вариант не должен работать для POD типов, для них ведь никак не сэмулировать второй вариант. В то время как для классов вцелом может.

C++
1
2
3
4
5
6
7
8
void function(int& v)
{
}
 
int main()
{
   function(1);
}
Мы пытаемся привязать константу к lvalue-reference, что абсолютно неверно.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
11.08.2014, 14:29 13
Цитата Сообщение от Toshkarik Посмотреть сообщение
Так ведь непонятно в данном случае - от чего защищают?
От бесполезной модификации временного объекта.
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
11.08.2014, 14:46  [ТС] 14
ForEveR, сейчас вопрос уже не в эмуляции, а в самом запрете. Ведь вполне можно было создать временный объект, даже POD, и передать его в функцию по ссылке, если гарантируется его время жизни ( временного объекта ).

Цитата Сообщение от Tulosba Посмотреть сообщение
От бесполезной модификации временного объекта.
Ну почему сразу бесполезной, вполне можно найти полезное применение. Ведь это одна из целей, как я понимаю, rvalue reference. Возможно, ошибаюсь.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
11.08.2014, 14:48 15
Цитата Сообщение от Toshkarik Посмотреть сообщение
Ну почему сразу бесполезной, вполне можно найти полезное применение.
Как оно может быть полезным, если объект будет уничтожен после всех манипуляций?
0
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
11.08.2014, 15:02  [ТС] 16
Я уже не найду, наверно, статью, в которой показывались новшества C++11 и способы достижения некоторых из них в C++03( 98 ). Я ведь не настаиваю ни на чем. Просто хотелось бы понять "создателей" языка/стандартов. Если бы небыло хоть в чем то полезным, то я не нашел бы этого способа в интернете. Конечно, я понимаю, что экспериментаторов тоже хватает.
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
11.08.2014, 15:38 17
Цитата Сообщение от Toshkarik Посмотреть сообщение
Просто хотелось бы понять "создателей" языка/стандартов.
Они не боги, а такие же люди. Не каждая возможность языка имеет глубокий смысл и кейс к применению, где иначе было бы нельзя.
"If you think C++ is not overly complicated, just what is a “protected abstract virtual base pure virtual private destructor,” and when was the last time you needed one?", - Tom Cargill (1990).
Цитата взята с седьмого слайда доклада: https://tech.yandex.ru/events/... alks/1954/
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,281
11.08.2014, 18:11 18
Цитата Сообщение от Toshkarik Посмотреть сообщение
Просто хотелось бы понять "создателей" языка/стандартов.
Защита в том числе от висячих ссылок. Уж больно просто их создать становится.
C++
1
2
С & c = C();
c.foo(); // fail
А так конечно любую защиту можно сломать, и если ты сейчас приведешь пяток способов создать висячую ссылку, то это не будет значить, что я не прав. А будет значить только лишь то, что нет в мире совершенных инструментов (наш мозг в том числе).
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
11.08.2014, 21:08 19
C++
1
2
С & c = C();
c.foo(); // fail
DrOffset, а как же:
There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context is when a default constructor is called to initialize an element of an array. If the constructor has one or more default arguments, the destruction of every temporary created in a default argument is sequenced before the construction of the next array element, if any.


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:
— 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.
— The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
— A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer.

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, thread, or automatic storage duration
1
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,281
11.08.2014, 21:41 20
Цитата Сообщение от Croessmah Посмотреть сообщение
а как же:
Все это хорошо, только не понятно к чему ты это написал. Никаких откровений я тут не увидел.
Я честно пытался угадать что ты имел в виду, но что-то не выходит. Поясни.

Добавлено через 8 минут
Хотя я кажется догадался. Если каким-либо образом нарушить вышеописанные правила, то получим висячие ссылки. Ну так на это у меня как раз была заготовлена фраза:
Цитата Сообщение от DrOffset Посмотреть сообщение
если ты сейчас приведешь пяток способов создать висячую ссылку, то это не будет значить, что я не прав. А будет значить только лишь то, что нет в мире совершенных инструментов (наш мозг в том числе).
С++ не из тех языков, которые будут поддерживать штаны разработчика. Следовательно ожидать от него чрезмерной заботы не стоит. Достаточно уже того, что все эти моменты описаны в стандарте. Если подумать, то легко можно объяснить, почему такие вещи не запрещены синтаксисом. Я думаю, ты и сам это знаешь.
0
11.08.2014, 21:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.08.2014, 21:41
Помогаю со студенческими работами здесь

Интерфейс, в методе которого создается объект типа IDictionary и возвращается ссылка на этот объект
Привет всем. Необходимо реализовать интерфейс, в методе которого создается объект типа IDictionary...

Ссылка на объект класса
class Aclass{ public: int i=0; void j(){i=2;} }; Aclass f(){ Aclass w; ...

Ссылка на объект класса в массиве
Вообщем есть класс THypergraph в котором находятся два массива объектов класса TGraphObject: ...

Ссылка на объект, возвращаемый функцией
Безопасно ли подобное? typedef std::vector< string > vec; vec someFoo(); vec someBoo() { //...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru