Недавно один товарищ на мой вопрос по языку С++ заметил «У… батенька мы даже не знаем разницы между ссылкой и указателем! Темнота!..» Для меня, честно говоря, это оказалось откровением. В литературе я не встречал чёткого разграничения этих понятий и воспринимал их как синонимы. Поиски ничего не дали. Так в чём же разница?
Здравствуйте, alex_ant, Вы писали:
_>Недавно один товарищ на мой вопрос по языку С++ заметил «У… батенька мы даже не знаем разницы между ссылкой и указателем! Темнота!..» Для меня, честно говоря, это оказалось откровением. В литературе я не встречал чёткого разграничения этих понятий и воспринимал их как синонимы. Поиски ничего не дали. Так в чём же разница?
Здравствуйте, alex_ant, Вы писали:
_>Недавно один товарищ на мой вопрос по языку С++ заметил «У… батенька мы даже не знаем разницы между ссылкой и указателем! Темнота!..» Для меня, честно говоря, это оказалось откровением. В литературе я не встречал чёткого разграничения этих понятий и воспринимал их как синонимы. Поиски ничего не дали. Так в чём же разница?
Разница в том, что ссылка — это второе имя переменной. И на этапе компиляции компилятор заменяет ссылку нужным именем. Вот и все.
Здравствуйте, alex_ant, Вы писали:
_>Недавно один товарищ на мой вопрос по языку С++ заметил «У… батенька мы даже не знаем разницы между ссылкой и указателем! Темнота!..» Для меня, честно говоря, это оказалось откровением. В литературе я не встречал чёткого разграничения этих понятий и воспринимал их как синонимы. Поиски ничего не дали. Так в чём же разница?
1. Ссылка уже разименована.
2. Ссылка не мжет быть NULL
3. Указатель можно инициализировать много раз, ссылку — ровно один.
Здравствуйте, memorilik, Вы писали:
<skipped> M>Разница в том, что ссылка — это второе имя переменной. И на этапе компиляции компилятор заменяет ссылку нужным именем. Вот и все.
И чем тут будет заменена ссылка на этапе компиляции?
// 1void Foo( int& result )
{
///.....
}
// 2void Foo( int* p )
{
if (!p )return;
int& ref=*p;
//.....
}
Здравствуйте, LuciferMoscow, Вы писали:
LM>2. Ссылка не мжет быть NULL LM>3. Указатель можно инициализировать много раз, ссылку — ровно один.
Я как-то раз наткнулся на такую конструкцию в ATL(?). Что-то типа
union
{
long* px;
long& rx;
//....
};
Явно написана грязными извращенцами
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: В чём разница ссылки от указателя?
От:
Аноним
Дата:
05.05.06 07:36
Оценка:
Здравствуйте, LuciferMoscow, Вы писали:
LM>Здравствуйте, alex_ant, Вы писали:
_>>Недавно один товарищ на мой вопрос по языку С++ заметил «У… батенька мы даже не знаем разницы между ссылкой и указателем! Темнота!..» Для меня, честно говоря, это оказалось откровением. В литературе я не встречал чёткого разграничения этих понятий и воспринимал их как синонимы. Поиски ничего не дали. Так в чём же разница? LM>1. Ссылка уже разименована. LM>2. Ссылка не мжет быть NULL LM>3. Указатель можно инициализировать много раз, ссылку — ровно один.
Добавлю:
4. Указатель — это lvalue, тоесть указатель сам имеет адрес, а ссылка адреса не имеет.
Здравствуйте, LuciferMoscow, Вы писали:
LM>2. Ссылка не мжет быть NULL
int val = 10;
int *p = &val;
// жил был указатель, тут его обнуляем...
p = NULL;
// а здесь получаем ссылку. увы ссылка нулевая и проверить уже никак не можем.int &ref = *p;
ref++;
P> int val = 10;
P> int *p = &val;
P> // жил был указатель, тут его обнуляем...
P> p = NULL;
P> // а здесь получаем ссылку. увы ссылка нулевая и проверить уже никак не можем.
P> int &ref = *p;
P> ref++;
P>
А здесь мы получаем не ссылку, а UB из-за разыменовывания нулевого указателя.
Здравствуйте, pullover, Вы писали: LM>>2. Ссылка не мжет быть NULL P>
P> int val = 10;
P> int *p = &val;
P> // жил был указатель, тут его обнуляем...
P> p = NULL;
P> // а здесь получаем ссылку. увы ссылка нулевая и проверить уже никак не можем.
P> int &ref = *p;// ВОТ ТУТ МЫ ПОЛУЧАЕМ НЕОПРЕДЕЛЕННОЕ ПОВЕДЕНИЕ
P> ref++;// А этот код вполне корректен
P>
Можно ли сунуть пальцы в розетку? Можно! Но зачем?!
Когда я говорю "не может быть NULL" я имею ввиду следующее:
class A;
void Foo(A& ref)
{
ref.CallSomeFoo();// Код полностью корректен
};
void Foo(A* ptr)
{
ptr->CallSomeFoo();// Код не корректен. Получаем интересное поведение при передаче нулевого указателя и по ушам от начальства :maniac:
}
>Всем огромное спасибо! Воистину век живи, век учись...
только я бы сказал, что форум — не место для изучения азов: разница между ссылкой и указателем описана в любой книжке по с++
2.3.10
Ссылка является другим именем объекта... Очевидным способом реализации ссылки является константный
указатель...
2.4.6
...компилятор может несколькими путями
воспользоваться тем, что объект является константой (конечно, в
зависимости от того, насколько он сообразителен). Самое очевидное —
это то, что для константы не требуется выделять память, поскольку
компилятор знает ее значение.
Здравствуйте, Вумудщзук, Вы писали:
В>только я бы сказал, что форум — не место для изучения азов: разница между ссылкой и указателем описана в любой книжке по с++
Страуструп в "ЯП C++, Спец издание" дает описание ссылки на странице 137. А спустя 300 страничек показывает еще одно отличие (разное поведение при dynamic_cast), которое сам называет фундаментальным.
Такой разброс хоть и вызывает недоумение, но является логичным для учебника. Вот и получается, что иногда, кроме как на сильном форуме, увидеть полный список отличий негде.
"alex_ant" <52470@users.rsdn.ru> wrote in message news:1883420@news.rsdn.ru... > Недавно один товарищ на мой вопрос по языку С++ заметил «У… батенька мы даже не знаем разницы между ссылкой и указателем! Темнота!..» Для меня, честно говоря, это оказалось откровением. В литературе я не встречал чёткого разграничения этих понятий и воспринимал их как синонимы. Поиски ничего не дали. Так в чём же разница?
По своему внутреннему представлению указатель и ссылка действительно одинаковы.
А вот с точки зрения использования, разница состоит в следующем:
1. Указатель можно перенаправить на другой объект, ссылка же инициализируется только один раз при создании и не может быть перенаправлена.
2. Для доступа к данным через указатель используются операторы * и ->. Так же к указателю применим оператор индексирования []. Доступ к данным по ссылке по форме выглядит так, как будто работа идет непосредственно с самой переменной, если это структура или класс, то доступ к членам осуществляется через оператор "точка".
3. Результатом взятия адреса указателя является адрес ячейки памяти, в которой хранится сам указатель. Адресом ссылки же будет адрес объекта, адресуемого ссылкой.
4. Ссылка может обеспечвать время жизни временной переменной: пока жива ссылка, будет жива и временная переменная.
Если говорить коротко, то ссылку можно считать указателем, который всегда разыменован автоматически.
Posted via RSDN NNTP Server 2.0
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, alex_ant, Вы писали:
_>Недавно один товарищ на мой вопрос по языку С++ заметил «У… батенька мы даже не знаем разницы между ссылкой и указателем! Темнота!..» Для меня, честно говоря, это оказалось откровением. В литературе я не встречал чёткого разграничения этих понятий и воспринимал их как синонимы. Поиски ничего не дали. Так в чём же разница?
в C++ и указатели и ссылки косвенно ссылаются на обьект.
Два различия:
1. ссылка всегда обязана ссылаться на обьект, тогда как указатель может быть равен нулю.
2. после инициализации ссылки нельзя изменить то, куда она ссылается, а для указателей это возможно.