Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: & или *  (Прочитано 15262 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« : 19-12-2006 06:27 » 

С студенческих времен так и не усвоил чем различается предача параметра  как указатель от передачи как ссылка

Например
OpenKey(HKEY & hKey)
от
OpenKey(HKEY * hKey)
Записан

Да да нет нет все остальное от лукавого.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 19-12-2006 06:47 » 

Тем, что со ссылкой нельзя работать, как с указателем Улыбаюсь Например, присвоить ей NULL.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
kisilevski
Постоялец

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 19-12-2006 06:56 » 

Ещё тем, что по ссылке в функцию приходит уже нормальная пеерменная, а по адресу может прийти "ерунда" - непроинициализированный адрес, или NULL (это особенно актуально, если твою функцию  вызывает другой участник проекта).
Записан

Ложки нет. See MSDN for details.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #3 : 19-12-2006 07:37 » 

опять же ссылку не надо разименовывать Улыбаюсь
я предпочитаю ссылки, там где возможно
Записан

Странно всё это....
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 19-12-2006 08:08 » 

Ещё тем, что по ссылке в функцию приходит уже нормальная пеерменная, а по адресу может прийти "ерунда" - непроинициализированный адрес, или NULL (это особенно актуально, если твою функцию  вызывает другой участник проекта).
Ну это не совсем так.
Ссылки и указатели предназначены для разных задачь. Сылки сделанны для предотврашения разных манимуляций с адрессом и это их главная задача, уберечь адрес от изминения.
Записан
kisilevski
Постоялец

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 19-12-2006 08:18 » 

Конечно, для разных - я же не сказал, что ссылки - это абсолютно везде абсолютная панацея. Сам и с адресами и со ссылками много работаю, но там, где есть возможность выбирать - выбираю ссылки.
Записан

Ложки нет. See MSDN for details.
s_n
Постоялец

ru
Offline Offline

« Ответ #6 : 19-12-2006 09:12 » 

Цитата
   
         Часть 8в. Ссылки
   120. Ссылочные аргументы всегда должны быть константами
   121. Никогда не используйте ссылки в качестве результатов, пользуйтесь указателями
   Использование ссылочных аргументов в языке программирования вызвано четырьмя причинами:
•   Они нужны вам для определения конструктора копии.
•   Они нужны вам для определения перегруженных операций. Если вы определили:
   some_class *operator+( some_class *left, some_class *right );
   то вы должны сделать такое дополнение:
   some_class x, y;
   x = *(&x + &y)
   Использование ссылок для аргумента и возвращаемого значения позволяет вам написать:
   x = x + 1;
•   Вы часто хотите передать объекты по значению, исходя из логики. Например, вы обычно в функцию передаете тип double, а не указатель на double. Тем не менее, тип double представляет собой 8-байтовую упакованную структуру с тремя полями: знаковым битом, мантиссой и порядком. Передавайте в этой ситуации ссылку на константный объект.
•   Если объект какого-нибудь определенного пользователем класса обычно передается по значению, то используйте вместо этого ссылку на константный объект, чтобы избежать неявного вызова конструктора копии.
   Ссылки в языке не предназначены для имитации Паскаля и не должны использоваться так, как используются в программе на Паскале.
.........
   Подведем итог: Я решаю, нужно или нет использовать ссылку, вначале игнорируя факт существования ссылок. Входные аргументы функций передаются по значению, а выходные — используют указатели на то место, где будут храниться результаты. Я затем преобразую те аргументы, которые передаются по значению, в ссылки на константные объекты, если эти аргументы:
•   являются объектами какого-то класса (в отличие от основных типов, подобных int);
•   не модифицируются где-то внутри функции.
Объекты, которые передаются по значению и затем модифицируются внутри функции, конечно должны по-прежнему передаваться по значению.

122. Не возвращайте ссылки (или указатели) на локальные переменные
Эта проблема проявляется и в Си, где вы не можете вернуть указатель на локальную переменную. Не возвращайте ссылку на объект, который не существует после этого возврата.
..........

123. Не возвращайте ссылки на память, выделенную оператором new
Каждый вызов new должен сопровождаться delete — подобно malloc() и free().
..........

(с) Ален И. Голуб, "ВЕРЕВКА ДОСТАТОЧНОЙ ДЛИНЫ, ЧТОБЫ… ВЫСТРЕЛИТЬ СЕБЕ В НОГУ"
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #7 : 19-12-2006 12:12 » 

пункт 121 слишком категоричен для того, что бы согласится со всеми утверждениями
изящьность и доступность для понимания кода для меня важнее.
Записан

Странно всё это....
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 19-12-2006 12:53 » 

Пользуйтесь ссылками вместо указателей, если для указателя недопустимо значение 0. 
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
s_n
Постоялец

ru
Offline Offline

« Ответ #9 : 19-12-2006 13:43 » 

В книге более подробно обосновывается каждый пункт, если интересно можно почитать (в клубе она помоему есть). Некоторые правила для "обычной жизни" не совсем подходят из-за того, что книга ориентирована на работу в команде разработчиков и подразумевает многократное использование написанного кода другими програмистами среднего уровня.

В частности к пунктам 120, 121 приводиться след. пример:

Цитата
Проблема ссылочных аргументов - сопровождение. В прошлом году один из наших сотрудников написал следующую подпрограмму:
void copy_word( char *target, char *&src ) { // src является ссылкой на char*
  while( isspace(*src) )
  ++src; // Инкрементировать указатель,
           // на который ссылается src.
  while( *src && !isspace(*src) )
  *target++ = *src++; // Передвинуть указатель,
                               // на который ссылается src,  за текущее слово.
}
Автор полагал, что вы будете вызывать copy_word() многократно. Каждый раз подпрограмма копировала бы следующее слово в буфер target и продвигала бы указатель в источнике.

Вчера вы написали следующий код:
f( const char *p ) {
  char *p = new char[1024];
  load( p );
  char word[64];
  copy_word( word, p );
  delete( p ); // Сюрприз! p был модифицирован, поэтому
                  // весь этот участок памяти обращается в кучу мусора!
}
Главная проблема состоит в том, что, глядя на вызов copy_word( word, p ), вы не получаете подсказки о возможном изменении p в подпрограмме. Чтобы добраться до этой информации, вы должны взглянуть на прототип этой функции (который, вероятно, скрыт на 6-ом уровне вложенности в заголовочном файле). Огромные проблемы при сопровождении.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 19-12-2006 15:13 » 

Я бы этот случай так определил:

для случаев вида
Код: (C++)
void f(X &x)
{
   ...
   x = ... ; // подменяем объект
   ...
}
ссылки использовать опасно.

Однако для случаев вида
Код: (C++)
void f(X &x)
{
   ...
   x.setSomething(...); // изменяем объект
   ...
}
ссылки использовать полезно.

При этом разработчик функции всегда гарантированно знает, меняется ли внутри его функции объект или подменяется.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #11 : 20-12-2006 06:20 » 

Передача по не константной ссылке подразумевает, то что объект почти гарантировано будет изменён и то, что такую функцию вызывают именно ради изменения этого объекта.
Хотя согласен, что указатель и указатель на указатель требует от пользователя функции явного указания и как следствие более естественное понимание последствий своих действий.

Что же касается функции copy_word, то обычно подобные функци возвращают модифицированный указаетель не в переданном параметре, а через return.
Записан

Странно всё это....
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 20-12-2006 06:33 » 

А вообще приведённый пример с "сюрпризом" - это нарушение/незнание/отсутствие спецификаций на используемую функцию, и синтаксически эта проблема не решается. Разработчик, который воспользовался функцией не так, как предполагал автор функции, просто не знал, что предполагал автор - эта информация потерялась. И это вопрос уже организационный, а не языковой.

В общем случае char ** тоже может как меняться, так и не меняться, хотя, конечно, насторожит пользователя функции больше, нежели char *.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 20-12-2006 07:31 » new

В некоторых стандартах на оформление кода необходимо перед каждым параметром указывать на то, как он будет использоваться в функции - для чтения, записи или будет изменён

Код:
#define IN
#define OUT
#define UPDATE
void copy_word(OUT char *target, UPDATE char *&src )

эти модификаторы не проверяются компилятором и служат прежде всего для документации.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines