Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
#1

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

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

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

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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.08.2014, 03:24
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ссылка на временный объект (C++):

Временный объект - C++
Требуется создать при помощи конструктора временный объект. Затем присвоить временный объект вызвавшему(представленному через this) функцию...

Временный объект и конструктор копирования - C++
Добрый день! Столкнулся c задачкой в тесте: class A{ public: A(){ cout<<"A()"<<endl; } A(const A& a){ ...

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

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

Ссылка на объект класса - C++
class Aclass{ public: int i=0; void j(){i=2;} }; Aclass f(){ Aclass w; sA&w; //Как правильно сделать...

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

24
CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 691
Записей в блоге: 1
11.08.2014, 07:27 #2
Toshkarik, в первом случае ссылка на временный объект, вы сами себе и ответили. Во-втором — функция возвращает ссылку на A, у функции такие же параметры. Почему это не должно скомпилироваться?
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,293
11.08.2014, 08:56 #3
Цитата Сообщение от Toshkarik Посмотреть сообщение
Собственно, вопрос: почему он валиден?
Выражение A(); является rvalue. Причем неконстантным rvalue.
Метод getThis() возвращает lvalue.
Потому и валиден.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
11.08.2014, 12:51  [ТС] #4
Почему компилируется понянто. Вопрос в другом, почему в этом случая временный объект живет до выхода из функции. Интересует не техническая часть, а почему это допустили. По сути мы схитрили и все же использовали временный объект для передали по ссылке в качестве параметра.
0
0x10
2474 / 1647 / 247
Регистрация: 24.11.2012
Сообщений: 4,068
11.08.2014, 12:58 #5
Toshkarik, временные объекты пока выполняется выражение.
Мб кто-нибудь приведет прямо ссылку на стандарт.
0
soon
2542 / 1307 / 81
Регистрация: 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
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
11.08.2014, 13:07  [ТС] #7
И про это в курсе, имеется в виду full-expression, ссылку на стандарт сейчас не дам, так как не помню. Может опять неправильно выразился. Попробуем наоборот: если возможен второй вариант, то почему запретили первый? Это же выглядит немного как "хак". Может быть, это одна из причин появления rvalue-reference в C++11...

Не по теме:

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

0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
11.08.2014, 13:19 #8
Toshkarik, Как-то спрашивал про то, почему разрешена конверсия от rvalue к lvalue на SO, впринципе там ответили довольно полно: http://stackoverflow.com/questions/1...-visual-studio
2
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,293
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
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
11.08.2014, 14:02 #10
Цитата Сообщение от Toshkarik Посмотреть сообщение
По сути мы схитрили
Именно в этом всё дело. Стандарт дает (старается дать) защиту от явных ошибок. Но когда программист хочет обойти защиту, он ее обойдет.
1
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
11.08.2014, 14:23  [ТС] #11
Так ведь непонятно в данном случае - от чего защищают?
0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
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
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
11.08.2014, 14:29 #13
Цитата Сообщение от Toshkarik Посмотреть сообщение
Так ведь непонятно в данном случае - от чего защищают?
От бесполезной модификации временного объекта.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
11.08.2014, 14:46  [ТС] #14
ForEveR, сейчас вопрос уже не в эмуляции, а в самом запрете. Ведь вполне можно было создать временный объект, даже POD, и передать его в функцию по ссылке, если гарантируется его время жизни ( временного объекта ).

Цитата Сообщение от Tulosba Посмотреть сообщение
От бесполезной модификации временного объекта.
Ну почему сразу бесполезной, вполне можно найти полезное применение. Ведь это одна из целей, как я понимаю, rvalue reference. Возможно, ошибаюсь.
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
11.08.2014, 14:48 #15
Цитата Сообщение от Toshkarik Посмотреть сообщение
Ну почему сразу бесполезной, вполне можно найти полезное применение.
Как оно может быть полезным, если объект будет уничтожен после всех манипуляций?
0
11.08.2014, 14:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.08.2014, 14:48
Привет! Вот еще темы с ответами:

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

Ссылка на объект не указывает на экземпляр объекта - C++
Подскажите, в чем ошибка и как исправить. struct Node{ Node *prev; Point *point; Node() { prev = nullptr; ...

Ссылка на объект как свойство класса - C++
Добрый вечер. Есть 2 класса: сотрудники и компании. Если использовать БД то вопрос бы решался очень просто, он почитав не много понял...

Ссылка на объект не указывает на экземпляр объекта C++ - C++
Создана прога для расчета сопротивления резисторов. В основной функции в некоторых случаях он все считает, а в некоторых - вылетает вот с...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru