Доброго времени суток.
Вот вопросец небольшой, в каких случаях следует предпочесть ссылки, а в каких указатели?
Я раньше где-то читал, что, где возможно, лучше использовать ссылки — красивше выглядит. Так вот набрёл на проблему, когда имеется указатель, а функция принимает ссылку:
SomeFunc(Type& var)
{
// ...
}
Type* var= GetVar();
SomeFunc(var) // ???
Что выбрать?
1. Заменить параметр функции на указатель, а значит признать, что такая же ситуация может произойти и с другими ссылками.
2. Может есть возможность получить ссылку через указатель, не копируя память в другую переменную?
Здравствуйте Алекс Пронскявичус, Вы писали:
АП>2. Может есть возможность получить ссылку через указатель, не копируя память в другую переменную?
Если указатель валидный и не нулевой, то
Type* var= GetVar();
SomeFunc( *var ) // вобщем-то работает :-)
Здравствуйте Алекс Пронскявичус, Вы писали:
АП>Доброго времени суток. АП>Вот вопросец небольшой, в каких случаях следует предпочесть ссылки, а в каких указатели?
В общем принципиальной разницы нет, но все зависит от того, какого эффекта ты хочешь добиться. Ссылки были введены в С++, в частности, для удобства облегчения реализации перегрузки; дабы не менять семантику указателей в С.
АП>Я раньше где-то читал, что, где возможно, лучше использовать ссылки — красивше выглядит. Так вот набрёл на проблему, когда имеется указатель, а функция принимает ссылку:
АП>
АП>SomeFunc(Type& var)
АП>{
АП> // ...
АП>}
АП>
АП>Type* var= GetVar(); АП>SomeFunc(var) // ???
На счет красивше — может быть, однако очень часто рекомендуют делать так: если ф-ция должна изменить передаваемый ей параметр, то лучше передавать его через указатель — так яснее выглядит на передаваемой стороне.
АП>Что выбрать? АП>1. Заменить параметр функции на указатель, а значит признать, что такая же ситуация может произойти и с другими ссылками.
Уточни.
АП>2. Может есть возможность получить ссылку через указатель, не копируя память в другую переменную?
Ссылка — это псевдоним, значит можно создать ссылку, которая будет псевдонимом объекта, на который указывает указатель. Дело в том, что ссылка не является объектом в понимании С++, т.е. не может быть ссылок нассылку, нельхя получить адрес ссылки; в общем случае память под ссылку вообще может не выделяться — все зависит от конкретного случая, компилятора и т.п.
Здравствуйте Алекс Пронскявичус, Вы писали:
АП>Доброго времени суток. АП>Вот вопросец небольшой, в каких случаях следует предпочесть ссылки, а в каких указатели?
Я соглашусь с Dr_Sh0ck — почти без разницы, но указатели я использую тогда, когда хочу показать, что объект может быть изменен функцией:
f(x); // с x ничего не будет
f(&x); // можно ожидать изменения x
ИМХО так меньше "неожиданностей".
Кроме того, есть еще одна принципиальнвя разница между ссылками и указателями, — ссылка может быть проинициалзирована только один раз. Т.е.:
int i1=1, i2=2;
int &ref1=i1;
ref1=i2; // после этого ссылка не станет ссылаться на i2, но i1 станет равна 2!!!
Здравствуйте Алекс Пронскявичус, Вы писали:
АП>Доброго времени суток. АП>Вот вопросец небольшой, в каких случаях следует предпочесть ссылки, а в каких указатели? АП>Я раньше где-то читал, что, где возможно, лучше использовать ссылки — красивше выглядит.
Я читал кажется у Элджера, что он советует использовать ссылки для лаконичности и простоты. А указатели использовать только тогда, когда передаваемый объект может не существовать (т.к. не может быть ссылки на NULL). Но я предпочитаю (как еще кто-то в этой теме уже писал)использовать указатели, чтоб подчеркнуть, что объект может быть изменен.
Здравствуйте kl, Вы писали:
kl>Просто не стоит использовать неконстантные ссылки, вот и все. К сожалению, при использовании сторонних библиотек это не всегда получается.
Насколько я помню, даже при использовании STL. Не говоря уж про MFC.
Здравствуйте kl, Вы писали:
kl>Здравствуйте yogi, Вы писали:
Y>>Здравствуйте Алекс Пронскявичус, Вы писали:
kl>Просто не стоит использовать неконстантные ссылки, вот и все. К сожалению, при использовании сторонних библиотек это не всегда получается.
Вопрос — чем эмулировать семантику неконстантной ссылки? Только указателем, так что этот совет изоморфен совету "использовать указатель для изменяемых параметров".
Здравствуйте Алекс Пронскявичус, Вы писали:
АП>в каких случаях следует предпочесть ссылки,
— Везде где надо передать параметр "по ссылке" — например чтобы вернуть результат выполнения функции
— Везде где желательно избежать передачи "по значению" — например можно передавать объект по значению, но при этом создается временая копия обьекта. Если обьект "большой" — это может быть дорого.
АП>а в каких указатели?
— То же что и выше, но возможен случай что параметр может быть "пустым" — т.е NULL
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Здравствуйте Vladik, Вы писали:
VV>Я соглашусь с Dr_Sh0ck — почти без разницы, но указатели я использую тогда, когда хочу показать, что объект может быть изменен функцией:
V>
V>f(x); // с x ничего не будет
V>f(&x); // можно ожидать изменения x
V>
Здравствуйте yogi, Вы писали:
Y>Здравствуйте Алекс Пронскявичус, Вы писали:
АП>>Доброго времени суток. АП>>Вот вопросец небольшой, в каких случаях следует предпочесть ссылки, а в каких указатели? АП>>Я раньше где-то читал, что, где возможно, лучше использовать ссылки — красивше выглядит.
Y>Я читал кажется у Элджера, что он советует использовать ссылки для лаконичности и простоты. А указатели использовать только тогда, когда передаваемый объект может не существовать (т.к. не может быть ссылки на NULL). Но я предпочитаю (как еще кто-то в этой теме уже писал)использовать указатели, чтоб подчеркнуть, что объект может быть изменен.
Вопрос о том, где использовать ссылку, а где указатель я для себя решил( следуя советам Круглински, да и судя по вашему ответу и Элджера) уже давно следующим образом:
Если значение нужно изменять, то передаю параметр по ссылке(будь это хоть DWORD).
Если объект изменять не надо и он достаточно громоздкий, то по ссылке на константный объект.
Указатели же использую только в тех функциях, которые манипулируют с паматью.
Здравствуйте Dr_Sh0ck, Вы писали:
DS>На счет красивше — может быть, однако очень часто рекомендуют делать так: если ф-ция должна изменить передаваемый ей параметр, то лучше передавать его через указатель — так яснее выглядит на передаваемой стороне.
"Так яснее выглядит" для обросших мохом сишников — которые привыкли что единственный способ передачи параметра "по ссылке" — это указатель. А если же параметр надо передать "по ссылке", но менять нельзя — применяется константная ссылка — "const type&"
Чем же ссылка хороша — а тем что, в отличие от указателя, она всегда корректна — то есть нет способа передать пуcтую ссылку. Точнее, он есть, но он требует вполне осознаннах телодвижений — такое по ошибке не сделаешь — в отличие от пустых и некорректных указателей.
Лично я применяю ссылки если мне надо передать параметр "по ссылке" (как вам каламбур?).
Это гарантирует (внутри функции) что данный параметр корректен и, следовательно, избавляет от дополнительных проверок на NULL и т.д.
ЗЫ.НЕ думайте что я против указателей. Они хороши. Но иногда ссылки — в особенности в качестве параметров функций, гораздо хорошее
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Здравствуйте Vladik, Вы писали:
V>Кроме того, есть еще одна принципиальнвя разница между ссылками и указателями, — ссылка может быть проинициалзирована только один раз. Т.е.: V>int i1=1, i2=2; V>int &ref1=i1; V> ref1=i2; // после этого ссылка не станет ссылаться на i2, но i1 станет равна 2!!!
Отнюдь.
int i1 = 1, i2 = 2;
int i3 = 3, i4 = 4;
int *ptr = &i1;
int &ref = i3; // это конструктор, а не оператор присваивания
// модификация ссылаемого объекта
*ptr = i2; // ptr == &i1; *ptr == i1 == i2 == 2
ref = i4; // &ref == &i3; ref == i3 == i4 == 4
// модификация ссылки
ptr = &i2;
&ref = &i4;
Считайте, что ссылка — это неявно разыменуемый указатель — и будет вам щастье.
Кстати, передавать ссылку в функцию — означает, что объект существует.
Потому что указатель может быть и нулевым (как вполне осмысленное значение).
Здравствуйте Алекс Пронскявичус, Вы писали:
АП>Доброго времени суток. АП>Вот вопросец небольшой, в каких случаях следует предпочесть ссылки, а в каких указатели? АП>Я раньше где-то читал, что, где возможно, лучше использовать ссылки — красивше выглядит. Так вот набрёл на проблему, когда имеется указатель, а функция принимает ссылку:
Здравствуйте Кодт, Вы писали:
К>Здравствуйте Vladik, Вы писали:
V>>Кроме того, есть еще одна принципиальнвя разница между ссылками и указателями, — ссылка может быть проинициалзирована только один раз. Т.е.: V>>int i1=1, i2=2; V>>int &ref1=i1; V>> ref1=i2; // после этого ссылка не станет ссылаться на i2, но i1 станет равна 2!!!
К>Отнюдь. К>