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

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

Войти
Регистрация
Восстановить пароль
 
Alexey104
1 / 1 / 0
Регистрация: 26.10.2014
Сообщений: 96
#1

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

13.07.2015, 21:37. Просмотров 446. Ответов 5
Метки нет (Все метки)

Здравствуйте!
В процессе экспериментов с С++ появились некоторые непонятки. Рассмотрим код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
using namespace std;
 
int& Func() {int a = 104; return a;}
 
int main()
{
  int c = Func();
  cout << c << "\n";
  return 0;
}
Ясен пень, данный код компилятор не хавает, поскольку в строке 5 производится попытка возврата из функции ссылки на локальную(временную) переменную этой функции. Я себе это представляю так:
Если бы компилятор позволил откомпилировать данный код, в строке 9 произошёл бы вызов функции, внутри которой была бы создана локальная переменная 'a'. Далее ссылка на эту переменную была бы возвращена из функции, а сама переменная после этого сразу была бы уничтожена. Затем в этой же строке произошла бы попытка инициализировать переменную 'c' ссылкой на уже не существующую переменную 'a'. Чтобы это предотвратить, компилятор уведомляет об ошибке.

Но прикол в том, что если строку 5 изменить следующим образом:
C++
1
int& Func() {int a = 104; int &b = a; return b;}
,
то код мало того, что компилируется, так ещё и корректно выполняется(строка 10 выводит на экран значение '104'). Никак не могу врубиться почему. Ведь, как и в первом случае, функция возвращает ссылку на временный объект. Может, компилятор не может "заглянуть" внутрь ссылки 'b' и увидеть, что она указывает на локальную переменную функции, поэтому и позволяет вернуть эту ссылку из функции? Но как же тогда переменная 'c' в строке 9 инициализируется этой ссылкой, если после её возврата(ссылки) из функции переменная 'a', на которую она указывает уничтожается?

Никто не прояснит ситуацию?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.07.2015, 21:37
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ссылки на временные объекты (C++):

Теория, Временные объекты - C++
Прошу ответить на пару вопросов. Конкретный вопрос: В тексте while (Pos != istream_iterator&lt;string&gt;()) {...} происходит ли...

Необязательные временные объекты - C++
Помогите с задачкой: Класс Car содержит модель автомобиля. Функция Find определяет, присутствует ли указанная модель в списке...

Временные объекты встроенного типа - C++
Привет! пытаюсь углубляться в C++, решил почитать книгу Саттера, на первом примере, остановился и запутался, там в конце, в виде советов,...

"Анонимные" (временные) объекты? - C++
Пусть имеется класс T: class T { public: int a; int b; T(int _a, int _b) : a(_a), b(_b) {} } Имеется функция void...

Создать указатели и ссылки на объекты в памяти - C++
Помогите, кто может Создайте в свободной памяти три объекта различных типов (Cat, Worker, Pencil…). Замените указатели ссылками и...

Ссылки на объекты в функции с не заданным типом переменных - C++
Как правильно передавать ссылки на объекты в функции с не заданным типом переменных и возможно ли это? Для общего случая я это...

5
Croessmah
Эксперт CЭксперт С++
13419 / 7573 / 855
Регистрация: 27.09.2012
Сообщений: 18,647
Записей в блоге: 3
Завершенные тесты: 1
13.07.2015, 21:49 #2
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Alexey104 Посмотреть сообщение
так ещё и корректно выполняется
это из-за полнолуния этот код приведет к UB
Цитата Сообщение от Alexey104 Посмотреть сообщение
то код мало того, что компилируется
ну так b же ссылка, а на что она там "нацелена", это уже никто проверять не будет.

Добавлено через 1 минуту
Цитата Сообщение от Alexey104 Посмотреть сообщение
Ведь, как и в первом случае, функция возвращает ссылку на временный объект.
на локальную переменную, которая будет уничтожена после выхода из функции

Добавлено через 1 минуту
Цитата Сообщение от Alexey104 Посмотреть сообщение
Но как же тогда переменная 'c' в строке 9 инициализируется этой ссылкой, если после её возврата(ссылки) из функции переменная 'a', на которую она указывает уничтожается?
ну так "сама ссылка" то остается, и "ссылается" туда же, просто там уже может быть что-то другое
1
Alexey104
1 / 1 / 0
Регистрация: 26.10.2014
Сообщений: 96
13.07.2015, 21:58  [ТС] #3
Спасибо, понятно!
0
Alexey104
1 / 1 / 0
Регистрация: 26.10.2014
Сообщений: 96
10.07.2017, 15:35  [ТС] #4
Всем привет!
Хотелось бы вернуться к теме ссылок на временные объекты и рассмотреть такой простенький пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
int Func1()
{
    int x = 8;
    return x;
}
 
int Func2(const int& x)
{
    return x;
}
 
int main()
{
    std::cout << Func2(Func1()) << "\n";
    return 0;
}
Хотелось бы лучше понимать процессы, происходящие при выполнении строки 16 данного нелепого кода:
Первым делом вызывается функция 'Func1()', внутри которой создаётся переменная 'x', инициализируемая некоторым значением(8). Переменная 'х' является локальным объектом 'Func1()', поэтому данная переменная уничтожается после того, как функция отрабатывет, а возвращается из функции временная копия этой переменной. Ссылка на эту временную копию передаётся в качестве аргумента функции 'Func2()'. Но корректно ли так делать? Будет ли ссылка на временную копию локального объекта функции 'Func1()' действительной на протяжении выполнения функции 'Func2()', или же 'Func2()' будет работать с уже 'мёртвой' ссылкой?

И ещё вопрос:
Если в строке 9 не указать, что ссылка, используемая в качестве аргумента функции 'Func2()', указывает на константу, GCC выдаёт:
temp.cpp: In function ‘int main()’:
temp.cpp:16:26: error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
std::cout << Func2(Func1()) << "\n";
~~~~~^~
temp.cpp:9:5: note: initializing argument 1 of ‘int Func2(int&)’
int Func2(int& x)
^~~~~

Что здесь хочет мне сказать компилятор? Читать я, конечно, умею, но смысла не улавливаю. Почему здесь так важно ключевое слово 'const'?
0
gray_fox
What a waste!
1521 / 1226 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
10.07.2017, 15:57 #5
Цитата Сообщение от Alexey104 Посмотреть сообщение
Но корректно ли так делать?
Вполне, ссылку на константу (const&) можно привязать временному объекту (т.е. к rvalue), тогда время жизни объекта продляется. Ссылку (&) - нельзя.
1
Alexey104
1 / 1 / 0
Регистрация: 26.10.2014
Сообщений: 96
10.07.2017, 16:31  [ТС] #6
gray_fox, Понятно, спасибо!
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.07.2017, 16:31
Привет! Вот еще темы с ответами:

Как правильно массиву объектов присвоить ссылки на объекты. - C++
TPoint Point,*p_Point; p_Point = Point; TPoint Mass; for (i=0; i&lt;10; i++) { Mass = p_Point; //вот не задвоятся ли у меня...

Функция создает объекты и указателями на них заполняет массив. При выходе из функции вызываются деструкторы объектов. Как сохранить объекты? - C++
Вопрос прост: как при выходе из функции сохранить объекты, которые были созданы в данной функции (указатели объектов положены в массив)?

В окне перемещаются объекты, отталкиваясь от стенок окна. Каждый объект имеет свой поток, перемещающий его. Встретившись, объекты начинают двигаться - C++
В окне перемещаются объекты, отталкиваясь от стенок окна. Каждый объект имеет свой поток, перемещающий его. Встретившись, объекты...

Временные диалоги Win32 API - C++
Во общем в Win32API я полный ноль, да и изучать мы его будем очень поврхностно и изучение закончится после сдачи заданий )), нам дали всего...


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

Или воспользуйтесь поиском по форуму:
6
Yandex
Объявления
10.07.2017, 16:31
Ответ Создать тему
Опции темы

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