0 / 0 / 0
Регистрация: 18.06.2014
Сообщений: 16
|
||||||
1 | ||||||
Возврат ссылки на закрытый элемент данных с++21.08.2015, 01:45. Показов 3993. Ответов 19
Метки нет (Все метки)
Я не могу понять как устроена проблема с возвратом ссылки на закрытый элемент данных.
Во вторых сама тема... Как устроена проблема с возвратом ссылки на закрытый элемент данных.
0
|
21.08.2015, 01:45 | |
Ответы с готовыми решениями:
19
Возвращение ссылки или указателя на закрытый элемент класса. Возврат ссылки Возврат r-ссылки Возврат ссылки |
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
|
21.08.2015, 01:59 | 2 |
int&link это такой int*link, только всегда разыменован (*link). В стандарте это вроде как немного другими словами, но техническая реализация ссылки 99% что будет именно через указатель.
Да как-то плевать закрытый он или открытый.
0
|
0 / 0 / 0
Регистрация: 18.06.2014
Сообщений: 16
|
|
21.08.2015, 02:19 [ТС] | 3 |
Тут,получается проблема в том что Privat переменную hour можно изменить в обход проверки в 4 строке.
И я пытаюсь понять этот механизм
0
|
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
|
21.08.2015, 02:30 | 4 |
А никакого механизма нет. Просто модификатор private это не более чем надпись на заборе и никакими защитными свойствами этот забор (переменную) не наделяет. Если компилятор замечает табличку "не влезай, убьет!" он на этот забор лезть отказывается. Если табличку спрятать (вернув ссылку), то полезет и ничего особенного не произойдет. Забор как забор.
2
|
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
|
||||||
21.08.2015, 02:38 | 5 | |||||
суть в том, что чисто технически данные, объявленные в области private являются закрытыми, что означает, что Вы не сможете напрямую получить к ним доступ, вот пример небольшой:
Напишите в main вот так:
Другое дело, что это считается дурным тоном.
1
|
0 / 0 / 0
Регистрация: 18.06.2014
Сообщений: 16
|
|||||||||||
21.08.2015, 02:52 [ТС] | 6 | ||||||||||
Возможно отхожу от темы...
в какой момент переменная hour принимает новое значение?
0
|
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
|
|||||||||||
21.08.2015, 03:05 | 7 | ||||||||||
Вот тут вы заблуждаетесь, вы создали функцию, которая возвращает ссылку на тип int.
Ссылка на функцию имеет немного иной вид:
Та часть объявления функции, которая находится позади имени функции, является возвращаемым типом функции. Добавлено через 5 минут Что касается вашего первого вопроса, рассмотрим тогда Ваш код:
Поскольку сейчас нас не интересует внутренняя реализация ссылок, проще всего думать(как во многих книгах написано), что ссылка, это всего лишь псевдоним объекта, которым она инициализируется. Так вот, поскольку у нас есть такой псевдоним(напомню его идентификатор hourRef), то когда мы пытаемся присвоить значение для hourRef, оно на самом деле присваивается объекту, на который указывает эта ссылка, то есть на закрытый член данных класса Time. Отсюда вывод и одновременно ответ на Ваш вопрос: hourRef = 30; После этой строки hour будет принимать новое значение.
1
|
0 / 0 / 0
Регистрация: 18.06.2014
Сообщений: 16
|
|
21.08.2015, 03:10 [ТС] | 8 |
с этим разобрался.
Если я правильно понял то я создал ссылку на то, что должна вернуть функция, в данном случае переменная hours?
0
|
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
|
|
21.08.2015, 03:11 | 9 |
В следующей строке у Вас также идет изменение этого члена данных, т.к. как я уже сказал, метод возвращает ссылку(псевдоним объекта), а значит есть смысл применить оператор = к вызову такого метода, после чего изменится значение ссылки.
Добавлено через 33 секунды Да.
1
|
0 / 0 / 0
Регистрация: 18.06.2014
Сообщений: 16
|
|
21.08.2015, 03:19 [ТС] | 10 |
Ну что бы закрепить материал, это return возвращает ссылку на hour или этому способствовал &перед именем функции. И вообще на что он( & перед именем функции) повлиял?
0
|
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
|
||||||||||||||||||||||||||
21.08.2015, 03:45 | 11 | |||||||||||||||||||||||||
Сообщение было отмечено vasea_morozov как решение
Решение
return и прочее, это все лишь текст, который транслирует компилятор.
Когда Вы определяете функцию, то попросту говоря, Вы даете инструкции компилятору, каким образом он должен генерировать объектный код. Так вот. Когда вы определяете функцию, предположим таким образом:
берет это в учет и когда дело в процессе компиляции дойдет до команды return, он уже не просто создает ячейку памяти, в которую кладет переменную указанную в команде return, с последующей копией в переменную, которой присваивается(или инициализируется), а он в Вашем случае, где переменная является ссылкой, заставляет ссылаться эту ссылку, на возвращенное значение. Таким образом работа уже происходит не с копией, а с самим элементом. Короче говоря, отсюда можно сделать вывод, что возвращаемый тип данных в некоторых ситуациях влияет на то, что вернет функция, не вдаваясь в подробности внутренней реализации компилятора. Попросту так: указанный тип возвращаемой функции, влияет на то, что должна возвращать функция через return. Добавлено через 4 минуты Ну вообще функции могут возвращать ссылки, указатели, и просто значение. Последние два случая идентичны. Если уж Вам так интересно, то представьте себе в самом упрощенном виде оперативную память, выделенную для работы программы как непрерывный блок данных. Представьте ячейки размером в 1 байт, много ячеек... Не вдаваясь в подробности работы стека:
в первом случае, если, при таком коде
Добавлено через 1 минуту Во втором случае:
возвращаемое значение foo(), то есть адрес, будет скопирован во временную ячейку в стеке, откуда будет скопирован в ячейку памяти, выделенную под хранение адреса типа int, то есть в нашу переменную ptr. После чего имеем возможно разыменовать этот указатель и изменить значение. Добавлено через 3 минуты в третьем случае:
В то время как при вызове версии для ссылки, мы можем изменить значение на которое она ссылается. В случае же с возвращаем по значению(последний вариант), если мы попытаемся изменить значение переменной var, будет изменено ее значение, которое всего лишь копия объекта. Добавлено через 3 минуты Конечно, ссылка скорей всего в компиляторе реализована как указатель, но это нас не касается. Главное думать о ссылках, что это не объекты, а псевдонимы объектов. Так как любое выражение с участием ссылки, будет на самом деле выражением с участием реального объекта, на который она ссылается. Именно по этой причине нет возможности изменить объект на который ссылается ссылка. Поэтому ссылки всегда надо инициализировать. Добавлено через 33 секунды Вообще мне кажется, о таком сейчас Вам не стоит задумываться. Просто изучите поведение ссылок и пишите код, практикуйтесь, потом само придет.
1
|
0 / 0 / 0
Регистрация: 18.06.2014
Сообщений: 16
|
|
21.08.2015, 14:09 [ТС] | 12 |
Большое спасибо! теперь я понял всё,о чём спрашивал!)
0
|
21.08.2015, 18:32 | 13 | |||||
Зная что хотел сделать программист можно было бы написать более корректный и очевидный пример.
0
|
:)
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
|
|||||||||||
22.08.2015, 14:34 | 14 | ||||||||||
В некоторых? Я бы сказал, что во всех!
Неудачная формулировка. Изменить объект можно, но нельзя изменить связь м/у ссылочной переменной и объектом, на который ссылка указывает. Проводя аналогию с указателями, можно было бы сказать, что ссылка (T&) работает как константный указатель на объект:
Обычно сеттеры либо возвращают void (в большинстве случаев), либо предыдущее установленное значение.
0
|
6 / 6 / 0
Регистрация: 03.08.2015
Сообщений: 25
|
|
22.08.2015, 14:57 | 16 |
TC не лепит. Программа взята у Дейтелов "Как программировать на C++"
0
|
22.08.2015, 15:15 | 17 |
А тогда понятен контекст...
Только пример не очень. Думаю понятно тут акцент на том что возвращая ссылку мы даем возможность задать значения в обход валидации -это плохо. А по сути там не должно быть ссылки потому что недолжно... т.е она там не нужна, у нас возвращается простой тип int так что ссылка не нужна.
0
|
6 / 6 / 0
Регистрация: 03.08.2015
Сообщений: 25
|
||||||
22.08.2015, 15:26 | 18 | |||||
так это только обучающая программа
представьте это в таком виде
1
|
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 455
|
||||||
23.08.2015, 18:14 | 19 | |||||
Ну можно было, да, но это бы еще больше его запутало. Т.к. пришлось бы объяснять верхний и нижний уровень модификатора типа const. К тому же большинство новичков юзают VS, где разрешена такая запись:
На счет неудачной формулировки связи ссылки с объектом, согласен, запутанно выразился.
1
|
:)
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
|
|
23.08.2015, 22:27 | 20 |
VS давно известна своим отступлением от Стандарта. Хотя в данном случае и выводит предупреждение:
В Стандарте на тему квалификаторов у ссылок сказано довольно четко (8.3.2/1):
1
|
23.08.2015, 22:27 | |
23.08.2015, 22:27 | |
Помогаю со студенческими работами здесь
20
Возврат ссылки из функции Возврат ссылки из метода Возврат ссылки на функцию. Возврат ссылки на указатель из функции Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |