27 / 27 / 4
Регистрация: 02.11.2010
Сообщений: 370
1

Ссылки vs Указатели

10.07.2012, 18:54. Показов 6817. Ответов 81
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Почему ссылки считаются более хорошим средством, чем указатели?
Ведь если человек будет использовать сторонние классы, он может не заметить, скажем
int &val
и не будет знать, что передается ссылка, а вовсе не копия. Это может повлечь за собой кучу неприятностей. Даже сам разработчик может спустя время забыть о злополучном знаке &. Так почему ссылки лучше?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.07.2012, 18:54
Ответы с готовыми решениями:

Указатели и ссылки c++
Здравствуйте! Не могли бы вы объяснить как можно использовать ссылки и указатели c++ на практике? Я...

Указатели и ссылки
Добрый день, есть вопросы по поводу указателей и ссылок в параметрах функций. Правильно ли я...

Ссылки, указатели
Доброго времени. Как, используя ссылки, указатели и, возможно, другие приемы сделать что-то вроде...

Ссылки и указатели
#include <iostream> using namespace std; int main() { int *n=new int{1,2};...

81
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
12.07.2012, 18:11 21
Author24 — интернет-сервис помощи студентам
Тоже добавлю, что кто-то из великих от плюсов (то ли Эккель, то ли Мейерс, то ли Саттер, а может кто-то ещё) советует в случае, если необходимо менять параметр, передаваемый в функцию, передавать этот параметр по указателю, чтобы программист при передаче такого параметра явно передавал адрес с помощью оператора &. Таким образом, скрытое изменение параметра в том случае, когда программист об этом не подозревает, можно считать плохим тоном.

Добавлено через 40 секунд

Не по теме:

Чёрт, а по факту-то сказал то же, что и Deviaphan... Ну да ладно, зато у меня в посте ещё три известных имени мелькает :D

2
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
12.07.2012, 18:19 22
Цитата Сообщение от Ksan Посмотреть сообщение
он может не заметить, скажем
int &val
Каким образом?
Цитата Сообщение от Ksan Посмотреть сообщение
и не будет знать, что передается ссылка, а вовсе не копия. Это может повлечь за собой кучу неприятностей.
В чём здесь преимущество указателей? По ним тоже передаётся оригинал, а не копия, причём, ещё и удаляемый. а по ссылке не удаляемый. Добавлено через 25 секунд
Цитата Сообщение от Ksan Посмотреть сообщение
Даже сам разработчик может спустя время забыть о злополучном знаке &.
А при чём здесь вообще забывчивость? Читай прототип и будешь знать, что передаёшь. А если ты & модешь забыть, то тем более забудешь букву в имени.

Добавлено через 2 минуты
Цитата Сообщение от Ksan Посмотреть сообщение
да даже, к примеру
Код C++
1
func(int &a);
& легко не заметить.
Не возможно и не только здесь, но и в прототипах на шесть-восемь экранов в длину, а они всё таки встречаются не часто.
1
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
12.07.2012, 18:24 23
Цитата Сообщение от taras atavin Посмотреть сообщение
прототипах на шесть-восемь экранов в длину
мда
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.07.2012, 18:26 24
Цитата Сообщение от Deviaphan Посмотреть сообщение
При передачи изменяемых объектов, используется указатель.
При передаче НЕ изменяемых объектов, используется константная ссылка.
При таком раскладе никто-никогда не забудет, что объект изменяется или не изменяется и все склеротики счастливы.
Делаю именно так. Идея передавать модифицируемый объект по ссылке мне не нравится в принципе. И мне было пофигу, что кругом люди поступают именно так. Очень рад, что я не одинок в подобном мнении
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
12.07.2012, 18:29 25
Ksan, ты функции на угад подбираешь, лишь бы параметры подошли? Тогда ты всё равно не сможешь программировать, так как при вызове функции надо точно знать, что именно она сделает, в том числе, как именно изменит параметр. А не изменит/не изменит. Ну а если переменная должна обнулиться, то в чём проблема? Ну передашь ты по значению и что? Параметр может и не изменится, но если ты функцию не знаешь, то она может много чего другого понаделать. В том числе, залезть в глобальную память и изменить переменные, которые ты не передавал.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.07.2012, 18:32 26
taras atavin, классическая ошибка, вызванная предположением, что программы только пишут. Но на самом деле программы ещё и читают. В том числе и чужие программы
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
12.07.2012, 18:35 27
Цитата Сообщение от Evg Посмотреть сообщение
Идея передавать модифицируемый объект по ссылке мне не нравится в принципе. И мне было пофигу, что кругом люди поступают именно так. Очень рад, что я не одинок в подобном мнении
Ни один разработчик функции, экспортируемой из библиотеки, в здравом уме не станет принимать и возвращать ссылки. Но почему нельзя их юзать внутри одной программы? Я по указателям передаю или массивы, или наружу, остальное ссылками. И не изменяемое тоже, пока не возникнет необходимость использования макросов и явных констант в фактических параметрах (именованными константами не пользуюсь вообще).

Добавлено через 40 секунд
Цитата Сообщение от Evg Посмотреть сообщение
taras atavin, классическая ошибка, вызванная предположением, что программы только пишут
Не моя.
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
12.07.2012, 18:48 28
Цитата Сообщение от Evg Посмотреть сообщение
Идея передавать модифицируемый объект по ссылке мне не нравится в принципе.
Мне нравится.) Если объект всегда необходимо передавать, то чаще именно ссылку использую. Экономия одного ассерта.)))
Но вариант с неконстантным указателем и константной ссылкой считаю более правильным и всем рекомендую к использованию.)

Добавлено через 1 минуту
Цитата Сообщение от taras atavin Посмотреть сообщение
но и в прототипах на шесть-восемь экранов в длину
Учитывая, что прототип это только имя функции и описание типов её аргументов, то я испытываю трепет от одной только мысли о размере реализации этой функции!

Добавлено через 2 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
именованными константами не пользуюсь вообще
По идее, после этого любой диалог нужно прекращать.
1
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
12.07.2012, 18:53 29
Deviaphan, silent_1991, Evg, отчасти с вами соглашусь, но как быть тому кто пишет отдельный независимый модуль, которым будут пользоваться другие? Понатыкать ассертов конечно можно, но это не всегда хороший выход из ситуации.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.07.2012, 19:02 30
Цитата Сообщение от Deviaphan Посмотреть сообщение
Мне нравится.) Если объект всегда необходимо передавать, то чаще именно ссылку использую. Экономия одного ассерта.)))
Предпочитаю экономить время на поиск ошибок, в том числе и другими людьми, которые будут впервые в жизни видеть мой код. Логика простая "funx(x)" не меняет значение x, а "func (&x)" - меняет. Человек, читающий код, вникнет в проблемное место намного быстрее, если не будет изучать прототип (а то и реализацию) каждой встретившейся функции. Спичечные экономии на assert'ах не особенно и интересны.

Цитата Сообщение от Jupiter Посмотреть сообщение
но как быть тому кто пишет отдельный независимый модуль, которым будут пользоваться другие?
А проблема-то в чём? А то может мы о разных вещах говорим
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
12.07.2012, 19:04 31
Цитата Сообщение от Jupiter Посмотреть сообщение
ассертов конечно можно, но это не всегда хороший выход из ситуации
Я только про те ситуации, когда параметр обязателен и 0 передавать низя.) По мне так лучше ассерт, чем что либо иначе. Но, как я выше уже написал, я тоже ссылки предпочитаю. Но в отдельных, не зависимых модулях, ссылки стараюсь всё таки не использовать. ДАже не уверен, что это возможно, потому что ни разу таких dll не делал.))))
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.07.2012, 19:07 32
Цитата Сообщение от Deviaphan Посмотреть сообщение
Я только про те ситуации, когда параметр обязателен и 0 передавать низя.)
В этом случае всё равно сломается на обращении по кривому адресу, а выявить проблему труда не составляет. Т.е. конкретно этот assert он скорее для красоты, чем для спасения мира
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
12.07.2012, 19:20 33
Цитата Сообщение от Evg Посмотреть сообщение
А проблема-то в чём? А то может мы о разных вещах говорим
ссылка и указатель как параметры функции, а проблема в том что код пишем не на один день и значит нужно принять "фундаментальное" решение о реакции на невалидный указатель

Не по теме:

Цитата Сообщение от Deviaphan Посмотреть сообщение
ДАже не уверен, что это возможно, потому что ни разу таких dll не делал.))))
мб я неточно выразился говоря модуль, что ж конкретизируем до хедер файла:)



Цитата Сообщение от Deviaphan Посмотреть сообщение
По мне так лучше ассерт, чем что либо иначе.
а что иначе? иначе только заставить передавать гарантировано инициализированный объект по ссылке
0
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
12.07.2012, 19:24 34
Jupiter, а в чём проблема-то всё-таки? Ссылку тоже можно инициализировать невалидным объектом.
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
12.07.2012, 19:27 35
Цитата Сообщение от Jupiter Посмотреть сообщение
а что иначе?
if и какой-нибудь возврат из функции. Или исключение. Но тут такая ошибка, что только на ассерт согласен.)

Цитата Сообщение от Jupiter Посмотреть сообщение
передавать гарантировано инициализированный объект по ссылке
Потому я и использую ссылки.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
12.07.2012, 19:46 36
Цитата Сообщение от silent_1991 Посмотреть сообщение
а в чём проблема-то всё-таки?
проблема в этом:
Цитата Сообщение от Deviaphan Посмотреть сообщение
if и какой-нибудь возврат из функции. Или исключение. Но тут такая ошибка, что только на ассерт согласен.)
чего можно избежать используя ссылку

Цитата Сообщение от silent_1991 Посмотреть сообщение
Ссылку тоже можно инициализировать невалидным объектом.
можно, но это уже будут проблемы того парня который инициализировал)
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
12.07.2012, 20:14 37
Цитата Сообщение от Jupiter Посмотреть сообщение
ссылка и указатель как параметры функции, а проблема в том что код пишем не на один день и значит нужно принять "фундаментальное" решение о реакции на невалидный указатель
Мне кажется, что тут вполне можно ограничиться тем, что написать в документации, что если ты злобный буратино, то библиотеку не используй. Т.е. если функция принимает параметр "struct trampampam*", то подсунув туда указатель на другой объект, получишь ошибку компиляции. А если сделаешь явное преобразование указателей, то ты и есть буратино.

Цитата Сообщение от silent_1991 Посмотреть сообщение
Ссылку тоже можно инициализировать невалидным объектом
А как? Мне казалось, что ссылки как раз и создавались для того, чтобы средствами языка их нельзя было инициализировать левотой. Хакерские методы не в счёт

Добавлено через 5 минут
На всякий случай. У меня слишком маленький опыт работы на Си++, а потому всё то, что я сказал - это всего лишь частное мнение, но НЕ экспертный взгляд
0
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
12.07.2012, 20:36 38
Цитата Сообщение от silent_1991 Посмотреть сообщение
Таким образом, скрытое изменение параметра в том случае, когда программист об этом не подозревает, можно считать плохим тоном.
не очень понимаю что тут скрытого..
передаем встроенный тип T - по значению (..., T t, ..)
передеем изменяемый - по ссылке (..., T& t, ..)
неизменяемый (..., const T& t, ..)
что неочевидного для пользователя?

Цитата Сообщение от Evg Посмотреть сообщение
А как? Мне казалось, что ссылки как раз и создавались для того, чтобы средствами языка их нельзя было инициализировать левотой. Хакерские методы не в счёт
подразумевается, что какойто имбецил напишет T& t = *((T*)NULL)
2
Эксперт С++
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
12.07.2012, 20:41 39
alex_x_x, не очевиден вызов:
C++
1
2
3
4
5
6
7
8
9
10
11
12
void print(int& a)
{
    std::cout << a << std::endl;
    
    a = 100500;
}
 
//...
 
int x = 10;
 
print(x);
С указателем так не выйдет, в месте вызова явно видно, что передаётся адрес, и значение по адресу может быть изменено.

Добавлено через 1 минуту
Evg, не знаю, стоит ли считать каст в стиле Си (или reinterpret_cast) хакерством, но многие пейсатели любят юзать подобные штуки, не задумываясь о последствиях. Причём в продакшн-коде.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
12.07.2012, 20:53 40
Цитата Сообщение от Evg Посмотреть сообщение
Мне кажется, что тут вполне можно ограничиться тем, что написать в документации, что если ты злобный буратино, то библиотеку не используй. Т.е. если функция принимает параметр "struct trampampam*", то подсунув туда указатель на другой объект, получишь ошибку компиляции. А если сделаешь явное преобразование указателей, то ты и есть буратино.
можно, вот только не факт что туда кто-то заглянет(а если заглянет, заметит!?), тогда как сигнатуру функции на 99.9% посмотрят
Цитата Сообщение от silent_1991 Посмотреть сообщение
С указателем так не выйдет, в месте вызова явно видно, что передаётся адрес, и значение по адресу может быть изменено.
указатели на константу не учитываем, всё равно придется глядеть сигнатуру)
0
12.07.2012, 20:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.07.2012, 20:53
Помогаю со студенческими работами здесь

Указатели и ссылки
Собственно, не могу до конца осознать как это работает, вот пример из вики(комменты входят в...

Указатели и Ссылки
извеняюсь,но никак не могу понять. int sum(int* inLeft, int* inRight) { if(inLeft ==...

Указатели и ссылки
Допустим, что есть функция, в которую мы кидаем массив по указателю и кол-ву элементов. void...

Ссылки и указатели
Здравствуйте, может кто объяснить в чем будет отличие при передаче в функцию по **, *, *&amp;, &amp;(**),...


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

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

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