ссылки и указатели
В чем принципиальная разница м\у ссылками и указателями, и когда ссылки использовать предпочтительнее:rolleyes:
{
*c = 'A'; // Явно разыменовываем.
}
void func2(char& c)
{
c = 'A'; // Неявно разыминовываем
}
2. Так же разница инициализации значения.
func1(&c); // Явно получаем адрес
func2(c); // Неявно получаем адрес
3. Значение указателя (адреса) можно менять, с ссылкой это не возможно.
3. Значение указателя (адреса) можно менять, с ссылкой это не возможно.
А при чём указатель к ссылке что то невразумею? Ссылки ж не указатели чтобы адрес можно было менять...., хотя если я не ошибаюсь ссылки это что то вроде автоматически разыменовываемых указателей и при присваивании меняется только значение по этому адресу, а не адрес.
В чем принципиальная разница м\у ссылками и указателями, и когда ссылки использовать предпочтительнее:rolleyes:
Какую книгу по C++ (хотя бы одну) ты прочитал прежде, чем постить этот вопрос?
Неужели в ней не рассказывалось про ссылки и указатели?
А поиском ты попробовал воспользоваться?
2. Так же разница инициализации значения.
func1(&c); // Явно получаем адрес
func2(c); // Неявно получаем адрес
3. Значение указателя (адреса) можно менять, с ссылкой это не возможно.
Ссылка - это псевдоним, поэтому разговор об адресе в данном контексте неправильный.
Такой вещи как "псевдоним" для процессора не существует, а вот адрес в памяти (указатель) - да. Машинный код для двух эквивалентных кусков со ссылкой и указателем будет одинаков. Поэтому я считаю ссылку неявным указателем.
[QUOTE=iridum]А при чём указатель к ссылке что то невразумею? Ссылки ж не указатели чтобы адрес можно было менять...., хотя если я не ошибаюсь ссылки это что то вроде автоматически разыменовываемых указателей и при присваивании меняется только значение по этому адресу, а не адрес.[/QUOTE]
Ты написал тож самое что и я.
Так для процессора нет такого понятия и как указатель. :D
Не факт, что "машинный код для двух эквивалентных кусков со ссылкой и указателем будет одинаков". Для какого процессора, какого компилятора и т.п.
Да даже для обычного x86 и популярного компилятора, например, cl от MS это НЕ ТАК !!!
Ну тогда давай говорить, что и циклов (for, while) в C++ нет, а есть только goto (он же jmp для процессора). Давай говорить, что нет никаких классов и методов классов, а есть области памяти и обычные функции (call), где есть один неявный аргумент this (обычно в регистре ecx). Давай говорить, что вообще нет никаких шаблонов, т.к. до процессора такое понятие вообще никак не доходит.
Давай говорить, что нет таких типов как int и unsigned int, т.к. в регистре всеравно будет dword.
Давай говорить что нет таких вещей, как sizeof, const, и т.п.
Зачем говорить о процессоре и низкоуровневом программировании, когда говоришь о высокоуровневом языке. Не надо путать понятия!
Нет для процессора такого понятия ссылка, зато оно есть для языке C++ !
P.S. Кстати, что есть "эквивалентный кусок" ?
2. Так же разница инициализации значения.
func1(&c); // Явно получаем адрес
func2(c); // Неявно получаем адрес
в контексте вопроса - причем тут данный код?
Почему? Чем DWORD PTR [eax] не разыминование указателя? :D
Да даже для обычного x86 и популярного компилятора, например, cl от MS это НЕ ТАК !!!
Да что вы? Давайте скомпилируем следующую программу с помощью VC 6.0:
{
*c = 'A';
}
void func2(char& c)
{
c = 'A';
}
int main()
{
char c;
func1(&c);
func2(c);
return 0;
}
И посмотрим листинг функции: func1 и func2.
; COMDAT ?func1@@YAXPAD@Z
_TEXT SEGMENT
_c$ = 8
?func1@@YAXPAD@Z PROC NEAR ; func1, COMDAT
; 3 : *c = 'A';
mov eax, DWORD PTR _c$[esp-4]
mov BYTE PTR [eax], 65 ; 00000041H
; 4 : }
ret 0
?func1@@YAXPAD@Z ENDP ; func1
_TEXT ENDS
PUBLIC ?func2@@YAXAAD@Z ; func2
; COMDAT ?func2@@YAXAAD@Z
_TEXT SEGMENT
_c$ = 8
?func2@@YAXAAD@Z PROC NEAR ; func2, COMDAT
; 8 : c = 'A';
mov eax, DWORD PTR _c$[esp-4]
mov BYTE PTR [eax], 65 ; 00000041H
; 9 : }
ret 0
?func2@@YAXAAD@Z ENDP ; func2
Так в чем разница?
Давай говорить, что нет таких типов как int и unsigned int, т.к. в регистре всеравно будет dword.
Давай говорить что нет таких вещей, как sizeof, const, и т.п.
Зачем говорить о процессоре и низкоуровневом программировании, когда говоришь о высокоуровневом языке. Не надо путать понятия!
Нет для процессора такого понятия ссылка, зато оно есть для языке C++ !
При чем тут это? Я не утверждаю что ссылки не существуют.
Зачем кидатся в крайности? Стандартом C++ не оговорена огранизация виртуальных функции, однако все знают про таблицу виртуальных функции.
Я считаю, что ссылка - это неявный указатель. Есть чем опровергнуть данное утверждение?
Это кусок кода делающий одно и тоже с помощью разных "инструментов".
См. пример выше.
ЗЫ. Ссылка - это синоним чего?
К разнице между ссылкой и указателем.
Тем, что ты путаешь языки программирования C++ и ассемблер x86.
Разыменование указателя в C++ - это не просто взятие значения по адресу содержащийся в указателе. Ты готов с этим спорить?
При чем тут это? Я не утверждаю что ссылки не существуют.
Буквально постом выше:
"Такой вещи как "псевдоним" для процессора не существует"
Зачем кидатся в крайности? Стандартом C++ не оговорена огранизация виртуальных функции, однако все знают про таблицу виртуальных функции.
Но ты же не утверждаешь на основании этого, что "Такой вещи как "виртуальный метод" для процессора не существует Поэтому я считаю виртуальный метод чем-то другим"
vtbl - лишь вариант реализации, бывают и другие реализации. Это механизмы скрытые от пользователя языком. И не стоит без крайней необходимости залезать в эту реализацию.
Ты знаком с термином "инкапсуляция"? Так вот считай, что vtbl и ссылки - это инкапсулированные вещи, нельзя завязываться на их реализацию, можно оперировать лишь интерфейсом. А интерфейсы у ссылок и указателей разные, поэтому можно с полной уверенностью говорить, что указатели и ссылки - разные вещи.
Да что вы? Давайте скомпилируем следующую программу с помощью VC 6.0:
<skip>
Так в чем разница?
Тогда получается, что нет разницы между программистом и дубом: и тот и другой растут, потребляют воду и воздух. Так в чем между ними разница? :D
Я считаю, что ссылка - это неявный указатель. Есть чем опровергнуть данное утверждение?
Да есть, конечно.
Сравни:
Вот тебе другой пример:
func(5 + 6);
Сможешь то же самое сделать для указателей?
Ещё пример:
вот указатель на указатель
если разницы нет, то сделай указатель на ссылку или ссылку на ссылку.
ЗЫ. Ссылка - это синоним чего?
Имени объекта.
Разыменование указателя в C++ - это не просто взятие значения по адресу содержащийся в указателе. Ты готов с этим спорить?
Ты прав, не просто взятие:
"Такой вещи как "псевдоним" для процессора не существует"
А где тут про ссылки?
vtbl - лишь вариант реализации, бывают и другие реализации. Это механизмы скрытые от пользователя языком. И не стоит без крайней необходимости залезать в эту реализацию.
Ты знаком с термином "инкапсуляция"? Так вот считай, что vtbl и ссылки - это инкапсулированные вещи, нельзя завязываться на их реализацию, можно оперировать лишь интерфейсом. А интерфейсы у ссылок и указателей разные, поэтому можно с полной уверенностью говорить, что указатели и ссылки - разные вещи.
Тогда получается, что нет разницы между программистом и дубом: и тот и другой растут, потребляют воду и воздух. Так в чем между ними разница? :D
Дык, а где я утверждаю что ссылки и указатели это одно и тоже? Ссылка - это неявный указатель
а не
Ссылка - это указатель.
Инкапсуляция инкапсуляцией, однако она никак не противоречит представлению ссылки как неявного указателя.
Да есть, конечно.
Сравни:
Вот тебе другой пример:
func(5 + 6);
Сможешь то же самое сделать для указателей?
Ещё пример:
вот указатель на указатель
если разницы нет, то сделай указатель на ссылку или ссылку на ссылку.
Ты мне доказываешь что ссылка это не указатель. Я с этим не спорю.
Я утверждаю что ссылка это неявный указатель. И из этого никак не следует, что указатели и ссылки должны иметь одинаковый интерфейс.
Где тут объект?
Или
Где тут имя объекта?
а где там указатель? :)
func2(c); ???
func2(c); ???
Строчкой выше. :) Тут ссылка создается.
Т.е. теперь вот это точный аналог разыменования указателя в С++ ? :D :D
[QUOTE=Green]
Буквально постом выше:
"Такой вещи как "псевдоним" для процессора не существует"
А где тут про ссылки?
[/QUOTE]
Ну началась игра в слова.
Псевдоним == Ссылка
Или для процессора такая вещь, как "ссылка" существует, а "псевдоним" - нет?
Дык, а где я утверждаю что ссылки и указатели это одно и тоже? Ссылка - это неявный указатель
а не
Ссылка - это указатель.
Инкапсуляция инкапсуляцией, однако она никак не противоречит представлению ссылки как неявного указателя.
Тогда стек - это массив, а еще стек может быть представлен списком. Видишь противоречие, если затачиваться на реализацию.
Так и с ссылкой: можно огрести если пытаться рассматривать её как неявный указатель. Само понятие "неявный", как-то "неявно", т.к. уж слишком много условий, отличающих ссылку от указателя.
Ты мне доказываешь что ссылка это не указатель. Я с этим не спорю.
Я утверждаю что ссылка это неявный указатель. И из этого никак не следует, что указатели и ссылки должны иметь одинаковый интерфейс.
Из примеров следует, что они не только имеют разный интерфейс, но и принципы их оперирования разные.
Где тут объект?
Объект типа char, расположенный по адресу 0.
Или
Где тут имя объекта?
Имени нет, но есть псевдоним.
Ты знаешь фамилию Неизвестного солдата?
Вот и здесь фамилии нет, а псевдоним есть.
Итак без адреса таки не обойтись. :)
Ты знаешь фамилию Неизвестного солдата?
Вот и здесь фамилии нет, а синоним есть.
Какой-то неправильный синоним.
Это ты сказал, не я. Кстати, я кажется, уже показал что это какое-то не полное объяснение.
Существует указатель (он же значение адреса), а ссылка это неявный указатель (т.е. абстракция, которая упрощает процесс разработки за счет отсутствия необходимости разименовывания, однако сути это не меняет). А вот с псевдонимом (он же синоним) как-то непонятно.
Любая область памяти может быть представлена как список или массив. Как это соотносится со ссылками?
Так и с ссылкой: можно огрести если пытаться рассматривать её как синоним. Само понятие "синоним" слишком неверное, т.к., как мы уж выяснили, ссылка может ссылатся не только на объекты у которых есть имена. :)
Под неявным я понимаю указатль с автоматическим разименованием и вытекающими свойствами.
Они это кто?
Нет. Это был пример в ответе на вопрос. "Разыменование указателя в C++ - это не просто взятие значения по адресу содержащийся в указателе. Ты готов с этим спорить?". Пример, не более.
с какой радости? :-\
Итак без адреса таки не обойтись. :)
Ты уже юродствуешь.
Адрес тут не при чем. Это всего лишь единственная специфичная инф. об объекте, которая известна из твоего куска кода.
Какой-то неправильный синоним.
А кто говорил "синоним" ?
Псевдоним. И вполне правильный. Уж куда правильнее "неявных указателей".
Это ты сказал, не я. Кстати, я кажется, уже показал что это какое-то не полное объяснение.
Не видел, что ты пытался показать.
Существует указатель (он же значение адреса), а ссылка это неявный указатель (т.е. абстракция, которая упрощает процесс разработки за счет отсутствия необходимости разименовывания, однако сути это не меняет). А вот с псевдонимом (он же синоним) как-то непонятно.
Да всё понятно, просто ты рогом уперся.
Если ты считаешь, что ссылка лишь "упрощение процесса разработки за счет отсутствия необходимости разименовывания", то ты ошибаешься как минимум трижды:
1) ссылки разыменовываются,
2) суть ссылки несколько иная, чем у указателя,
3) ссылка не является полноценной переменной, т.к. у неё нет внутреннего состояния, иными словами, ссылка не содержит значения, т.е. ей нельзя присвоить некоторое значение (в т.ч. и нулевое) и нельзя к нему обратиться.
Поэтому (загибай пальцы, считаем, чем ссылка отличается от указателя):
1) ссылка не имеет собственного размера, sizeof ссылки равен размеру ссылаемого типа;
2) невозможна арифметика с ссылками;
3) невозможно определить указатель на ссылку;
4) невозможно ссылаться на ссылку;
5) попытка взять адрес ссылки (&), вернет адрес ссылаемого объекта;
6) невозможно использование ссылок в объединении (union);
7) невозможно создать массив ссылок;
8) возможна константная ссылка на rvalue: const int& i = 5;
А теперь смотрим, что общего у ссылки с указателем:
1) ссылка разыменовывается;
2) несколько ссылок могут ссылаться на один объект.
Т.о. ссылка не имеет ничего собственного (даже размера и адреса), с самого своего рождения ссылается на один единственный объект, все обращения перенаправляет на него, и т.о. является всего лишь псевдонимом этого объекта.
Любая область памяти может быть представлена как список или массив. Как это соотносится со ссылками?
Мое высказываение было о том, что инкапсуляция на то и придумана, что если завязываться на реализацию, можно огрести по полной программе. Поэтому при рассмотрении ссылок так же не стоит затачиваться на их реализацию на уровне процессора. Для высокоуровневого языка программирования процессора как бы не существует вовсе.
Так и с ссылкой: можно огрести если пытаться рассматривать её как синоним. Само понятие "синоним" слишком неверное, т.к., как мы уж выяснили, ссылка может ссылатся не только на объекты у которых есть имена.
Вот ты глупость сказал.
Какая разница, есть у объекта имя или нет? У него может быть псевдоним ("синоним" - это ты сказал, я говорю "псевдоним").
И как же мы можем огрести? :D
Покажи наглядный пример, того, как мы огребаем.
А я тебе покажу еще с пяток примеров, как ты реально огребаешь, считая ссылку всего лишь "указателем с автоматическим разыменованием".
Под неявным я понимаю указатль с автоматическим разименованием и вытекающими свойствами.
И какие же свойства вытекают из неявности. Твои объяснения "неявного указателя" такие же неявные как и он сам. :D
Удав - это тоже шланг с глазами и вытекающими свойствами. :D
Они это кто?
А о чем мы говорим? Смотри сабж, если так увлекся спором, что забыл о чем он: " ссылки и указатели"
Адрес тут не при чем. Это всего лишь единственная специфичная инф. об объекте, которая известна из твоего куска кода.
int* p = &x;
Я могу сказать, что (*p) это псевдоним (x), и попробуй докажи обратное.
Псевдоним. И вполне правильный. Уж куда правильнее "неявных указателей".
Ты сам говорил. В твоей цитате четко написано "синоним", а то что ты исправил свое сообщение после того как я начал на него отвечать, не мои проблемы. Кажется я уже дал расшифровку что я понимаю под неявным.
Что называть ссылку псевдонимом или синонимом - не верно. Ссылка ссылается на определенный адрес в памяти, как и указатели, но в отличае от последних автоматически разыменовывается. А псевдонимом или синоним чего является ссылка так и осталось не понятно. Может объяснишь?
Абсолютно так же как и ты.
1) ссылки разыменовываются,
Указатели тоже разыменовываются.
Так я не увидел принципиальной разницы, кроме автоматического разыменования и вытекающих свойтсв.
И опять как это противоречит моим словам?
1) ссылка не имеет собственного размера, sizeof ссылки равен размеру ссылаемого типа;
Ты забываешь про автоматическое разыменование.
char& i;
char* p;
Ты пытаешься сравнивать i и p, а я нужно i и *p. Т.к., повторюсь, ссылка автоматически разыменовывается и из этого следуют ее свойтсва с sizeof и пр.
3) невозможно определить указатель на ссылку;
4) невозможно ссылаться на ссылку;
5) попытка взять адрес ссылки (&), вернет адрес ссылаемого объекта;
6) невозможно использование ссылок в объединении (union);
7) невозможно создать массив ссылок;
8) возможна константная ссылка на rvalue: const int& i = 5;
Это вытекающее свойство из автоматического разыменования. И говорит только о том, что это виртуальный объект, который представлен указателем на (адресом) объекта на который ссылается. Не более.
1) ссылка разыменовывается;
2) несколько ссылок могут ссылаться на один объект.
3) ссылка может ссылатся на любой адрес в ОЗУ.
Если подумать можно еще много общего придумать. Будем мерить правильность позиции количеством аргументов суть которых сводится к различию в интерфейсе?
Ты прицепился к тому что у ссылки и указателя разный интерфейс. Но я с этим не спорю. Я утверждаю тоже самое.
Как представление ссылки как неявного указателя противоречит инкапсуляции?
Какая разница, есть у объекта имя или нет? У него может быть псевдоним ("синоним" - это ты сказал, я говорю "псевдоним").
В чем разница между синонимом и псевдонимом в данном случае? Псевдоноим подразумевает существование настоящего имени, как и синоним другого имени.
Покажи наглядный пример, того, как мы огребаем.
"Пседоним - вымышленное имя, заменяющее собой настоящее, к-рое по тем или иным причинам надо скрыть."
Я уже два примера показал. Непонятно псевдонимом чего являются там ссылка, ведь там настоящего имени и в помине нет.
Ты еще ни одного преимера не привел. Автоматическое разыменование несет в себе несколько больше, чем отсутствие * перед именем указателя.
1) разность размера
2) отсутсвие возможности изменить объект на который он ссылается
...
Это я для уточнения, т.к. ты из сообщение в сообщение пытаешься показать мне что ссылка это не указатель. Я говорю что я с тобой согласен. И ты мне даьше доказываеш то, с чем я согласен.
Ссылка != Указатель.
Но...
Ссылка == Неявный указатель (указатель с автоматическим разыменовыванием).
Поэтому я уточняю. Может ты уже про другое речь ведешь.
Потому что там выше определены функции func1 и func2, первая из которыйх получает в качестве аргумента указатель на переменную, а вторая ссылку на переменную. Соответственно, ссылка и указатель должны быть созданы перед передачей в функции.
int* p = &x;
Я могу сказать, что (*p) это псевдоним (x), и попробуй докажи обратное.
А чего здесь доказывать. Ты сам себя загнал в ловушку.
*p - вызов оператора разыменования, а (как ты конечно знаешь) синтаксис этого оператора следующий
T& operator*()
т.о. операция возвращает ссылку.
(*p) - не будет псевдонимом, это операция возвращающая псевдоним.
Кажется я уже дал расшифровку что я понимаю под неявным.
Да дурацкая формулировка, особенно в части "вытекающей".
"Вытекающие свойства" - слова без смысла, которые (см. мою подпись) объясняют любую аномалию.
Кирпич - тоже компьютер, но с автоматическим разыменованием и "вытекающими свойствами".
Слон - это муха но с ушами и "вытекающими свойствами".
А псевдонимом или синоним чего является ссылка так и осталось не понятно. Может объяснишь?
Да все уже известно и несколько раз объяснено.
А... я понял, в чем твоя проблема: ты просто не знаешь, что такое указатель, поэтому и не можешь понять в чем принципиальная разница между указателем и ссылкой.
Указатель - это переменная (полноценный объект), к которому применима операция разыменования, т.е. у этого объекта есть конкретный оператор разыменования (*, ->).
Ссылка - псевдоним, ещё одно имя объекта, это не переменная (не полноценный объект) и у него нет оператора разыменования.
Другими словами: указатель - реально существующий объект, который можно поторогать, а ссылка - лишь ещё одно имя объекта, лишь ещё один способ обратиться к объекту.
Так я не увидел принципиальной разницы, кроме автоматического разыменования и вытекающих свойтсв.
Я тебе привел 8 "принципиальных разниц". Ты этого так и не заметил?
Это вытекающее свойство из автоматического разыменования. И говорит только о том, что это виртуальный объект, который представлен указателем на (адресом) объекта на который ссылается. Не более.
Кто тебе сказал, что он представлен указателем?
Покажи мне этот указатель! Дай его пощупать!
3) ссылка может ссылатся на любой адрес в ОЗУ.
Если подумать можно еще много общего придумать.
Ну так придумай, приведи... :)
А твоё 3) отметается, т.к. в C++ нет адресов и ОЗУ (слишком низкоуровневые понятия), кроме того ссылка может ссылаться не только на объекты в пямяти.
Будем мерить правильность позиции количеством аргументов суть которых сводится к различию в интерфейсе?
Ты прицепился к тому что у ссылки и указателя разный интерфейс. Но я с этим не спорю. Я утверждаю тоже самое.
Я прицепился не к интерфейсу, а к разности сущностей. Ссылка вообще физической сущностью не является.
"Пседоним - вымышленное имя, заменяющее собой настоящее, к-рое по тем или иным причинам надо скрыть."
Ага, а "материнская плата" - плата взымаемая с матерей. :D
Я уже два примера показал. Непонятно псевдонимом чего являются там ссылка, ведь там настоящего имени и в помине нет.
В чем разница между синонимом и псевдонимом в данном случае? Псевдоноим подразумевает существование настоящего имени, как и синоним другого имени.
Псевдоним (в программировании) не подразумевает существования "настоящего имени". Это лишь ещё одно имя объекта.
[QUOTE=Green]
А я тебе покажу еще с пяток примеров, как ты реально огребаешь, считая ссылку всего лишь "указателем с автоматическим разыменованием".
Ты еще ни одного преимера не привел.
[/QUOTE]
Ты крайне невнимателен. Перечисляю уже привеные примеры:
func(5 + 6);
int&* pr; // невалидно
int&& rr; // невалидно
А теперь ещё раз прошу, покажи мне, как можно огрести, считая ссылку псевдонимом объекта.
После чего я покажу не академические приверы, а реальные проблемы возникающие при ссылок, если считать их "удобной заменой указателям".
Автоматическое разыменование несет в себе несколько больше, чем отсутствие * перед именем указателя.
Да нет такого понятия в С++, как "автоматическое разыменование".
Дай мне четкое определение твоего "автоматического разыменования".
Ссылка == Неявный указатель (указатель с автоматическим разыменовыванием).
А за одно дай определение "неявного указателя", только если там что-то вытекает, то перечисли, всё, что вытекает. Я хочу иметь формулировку четко отличающую "неявный указатель", от других сущностей этого мира.
да, уже понял, пасиб. я просто привык к С, а у тебя С++ :)
*p - вызов оператора разыменования, а (как ты конечно знаешь) синтаксис этого оператора следующий
T& operator*()
т.о. операция возвращает ссылку.
(*p) - не будет псевдонимом, это операция возвращающая псевдоним.
Ты кодом лучше покажи, не разрывая (*p). А так пока опять идет сравнение указателя и ссылки.
Не хуже псевдонима.
А... я понял, в чем твоя проблема: ты просто не знаешь, что такое указатель, поэтому и не можешь понять в чем принципиальная разница между указателем и ссылкой.
Указатель - это переменная (полноценный объект), к которому применима операция разыменования, т.е. у этого объекта есть конкретный оператор разыменования (*, ->).
Ссылка - псевдоним, ещё одно имя объекта, это не переменная (не полноценный объект) и у него нет оператора разыменования.
Другими словами: указатель - реально существующий объект, который можно поторогать, а ссылка - лишь ещё одно имя объекта.
Я знаю что такое указатель. Еще раз указатель != неявный указатель.
Твои аргументы сводятся к ссылка != указатель. Я уже устал на это указывать (вот такой вот каламбур).
Ты этого так и не заметил?
Я с тобой согласен ссылка != указатель. Только при чем тут неявный указатель я понять никак не могу. Где я говорю что у указателя и неявного указателя одинаковый интерфейс или принципы использования?
Покажи мне этот указатель! Дай его пощупать!
Легко. У ссылки есть оператор & который возращает значение указателя, который эта ссылка неявно представляет. Для других типов создается указатель на этот объект.
char& f = c;
&r; // вот так его можно получить, щупай наздоровье. ;)
А что храниться в указателе? Почему к указателям применимы арифметические операции? Если в указатели храниться не адрес, то что?
Ссылка может ссылатся на секторы жесткого диска? :D :D
Да, да, еще раз да. Ссылка и указатель это разные сущности. Я не против. :)
На основании чего сделан такой вывод? Каковы критерии физического существования?
А "ссылка" - это ссылка в Сибирь?
Еще одно (второе, третье, ...), а где первое-то? Где оно?
Дай мне четкое определение твоего "автоматического разыменования".
А за одно дай определение "неявного указателя", только если там что-то вытекает, то перечисли, всё, что вытекает. Я хочу иметь формулировку четко отличающую "неявный указатель", от других сущностей этого мира.
Дык, с С++ нет такого понятия как псевдоним. И четкого определения ссылки я пока не услышал как не просил.
Неявный указатель делает код меньше за счет снятия необходимости разыменования, в отличае от обычного указателя.
Возьмем пример.
int* p = &x; // явный указатель.
int& r = x; // неявный указатель.
*p = 10; // явно разыменовываем
r = 10; // неявно (автоматически) разыменовываем
Вытекающие свойства это все свойства которые отличают ссылку от указателя, которые ты уже перечислил. Они по разному определяются и имеют различные типовые параметры в C++.
Непонятно одно. Что такое неявный указатель ?
Я так понимаю что ты под этим понятием подразумеваеш чтото типа переменной, которая есть адресом данных в памяти.
Если да то сравнивать указатели с этим вот "неявный указатель" таки некорректно. Тут скорее можно провести аналогию с другими языками
Pascal:
Это ссылка.
А почему переменную нельзя назвать неявным указателем ??
Суть то одна. И то и то есть адресом области памяти (в большинстве случаев)
Суть то одна. И то и то есть адресом области памяти (в большинстве случаев)
Потому же, почему ее нельзя навзать ссылкой (или можно, это кто как считает). :)
{
public:
A * operator&()
{
system("format c:");
return this;
}
};
Теперь воспользоваться указателем на A, не отформатировав диск, нельзя. А ссылкой - пожалуйста! :)
Чую топикпастер сильно пожалел что тему поднял... И так не понимал чем отличаются, да еще и запутали
Чую топикпастер сильно пожалел что тему поднял... И так не понимал чем отличаются, да еще и запутали
топикпастер-у. Не буду утверждать но помойму в книге "Эффективное использование С++". Мэйерс Скотт Эта было доступно описано что когда лутше использовать.
Что тебе кодом показать?
Что операция *p возвращает ссылку? Ты это и сам должен знать, если считаешь, что знаешь C++.
Твои аргументы сводятся к ссылка != указатель. Я уже устал на это указывать (вот такой вот каламбур).
Только при чем тут неявный указатель я понять никак не могу. Где я говорю что у указателя и неявного указателя одинаковый интерфейс или принципы использования?
Только лишь потому, что ты так и не смог дать определения своему мистическому "неявному указателю".
Ты придумал какой-то "неявный указатель" - сущность известная только тебе и теперь мы играем в угадайку: "э нет мой неявный указатель - это не указатель, мой неявный указатель - это нечто такое со всеми вытекающими"
Легко. У ссылки есть оператор & который возращает значение указателя, который эта ссылка неявно представляет. Для других типов создается указатель на этот объект.
char& f = c;
&r; // вот так его можно получить, щупай наздоровье.
Фигово ты знаешь C++ !
Нет у ссылки оператора &.
И в твоем примере оператор применяется к ссылаемому объекту, а не к сылке.
Сам доказать это сможешь или опровергнуть? Просто не хочется мордочкой тыкать в такие элементарные ошибки.
[QUOTE=Green]
А твоё 3) отметается, т.к. в C++ нет адресов и ОЗУ (слишком низкоуровневые понятия)
А что храниться в указателе? Почему к указателям применимы арифметические операции? Если в указатели храниться не адрес, то что?
[/QUOTE]
Значение указателя, которое в общем случае является адресом.
Только при чем тут ОЗУ ?
В C++ нет такого понятия, как ОЗУ. Там есть такое понятие как память (причем нескольких видов, но и эта классификация не связана никак с понятием ОЗУ).
А память может быть реализована, как угодно (ОЗУ, ПЗУ, магнитная лента, ферритовые сердечники), это C++ не касается.
[QUOTE=Green]
, кроме того ссылка может ссылаться не только на объекты в пямяти.
Ссылка может ссылатся на секторы жесткого диска?
[/QUOTE]
Ну зачем, ты опять говоришь глупости и употребляешь понятия не по месту? Нет для C++ ни ОЗУ, ни секторов, ни даже процессора.
А высказывание моё касалось того, что ссылка, как я уже показывал выше, может ссылаться на rvalue, которое не обязательно должно быть "объектом в памяти".
На основании чего сделан такой вывод? Каковы критерии физического существования?
Читаем выше:
[QUOTE=Green]
Псевдоним (в программировании) не подразумевает существования "настоящего имени". Это лишь ещё одно имя объекта.
Еще одно (второе, третье, ...), а где первое-то? Где оно?
[/QUOTE]
У имен нет перечислений (первое, второе...). Просто, есть имя, есть ещё имя.
Нет было име, значит ссылка будет первым, если уж тебе так хочется перечислений.
Дык, с С++ нет такого понятия как псевдоним. И четкого определения ссылки я пока не услышал как не просил.
Ссылка - способ обращения к объекту. Именованная ссылка - способ обращения по имени, т.е. псевдоним.
Неявный указатель делает код меньше за счет снятия необходимости разыменования, в отличае от обычного указателя.
Возьмем пример.
int* p = &x; // явный указатель.
int& r = x; // неявный указатель.
*p = 10; // явно разыменовываем
r = 10; // неявно (автоматически) разыменовываем
Т.е. ссылка введена для того, чтоб не писать одну звездочку :D:D:D
Ты совершенно не понимаешь суть ссылок. СОВЕРШЕННО.
Перечитай мои посты в этой теме с самого сначала.
Вытекающие свойства это все свойства которые отличают ссылку от указателя, которые ты уже перечислил. Они по разному определяются и имеют различные типовые параметры в C++.
Короче, я так и не услышал определения "неявного указателя", а все твои рассуждения - это попытка притянуть объяснение за уши.
А дело все вот в чем.
Выражать сущность "ссылка" через сущность "указатель" в корне неверно, т.к. ссылка никак не соотносится с указателем (поэтому ты и запутываешь следы всякими "неявное", "вытекающее" и т.п.), а совсем даже наоборот - "указатель" выражается через "ссылку":
Указатель - объект, к которому применима операция разыменования, результатом которой является ссылка, которая (см. определение выше) является способом доступа к некоторому объекту.
Всё. Кратко и понятно. Нет никаких "неявных" и "вытекающих".
P.S. Вот пришла в голову метафора.
У человека есть имя, а есть паспорт.
Имя - сущность нематериальная, а паспорт - это объект.
Некорректно выражать понятие "имя" через понятие "паспорт", что ты пытаешься делать:
"Имя - это неявный паспорт с автоматическим прочтением"
а на самом то деле, это паспорт - документ (объект) содержащий имя человека (объекта).
P.P.S. Прежде, чем писать новый пост, сформулируй, пожалуйста, простое и однозначно понятное определение "неявного указателя".
Что операция *p возвращает ссылку? Ты это и сам должен знать, если считаешь, что знаешь C++.
int* p = &x;
int& r = x;
// Тут ниже любой код, который использует r.
Так вот покажи мне случай (приведи фрагмент кода), когда нельзя заменить r на (*p)? Кроме декларирования и инициализации p и r, разумеется.
Ты придумал какой-то "неявный указатель" - сущность известная только тебе и теперь мы играем в угадайку: "э нет мой неявный указатель - это не указатель, мой неявный указатель - это нечто такое со всеми вытекающими"
Т.е. ты не понимаешь то что пытаешься опровергнуть? :D
Раз тебе не понятна фраза "ссылка это неявный указатель", зачем ее сразу опровергать?
Нет у ссылки оператора &.
Обоснуй.
Обоснуй.
Потыкай. Ты меня уже тычешь несколько страниц, но вот только все сводиться к сравнению указетлей и ссылок, хотя при чем тут это - так и не понятно.
Покажи когда не является.
В C++ нет такого понятия, как ОЗУ. Там есть такое понятие как память (причем нескольких видов, но и эта классификация не связана никак с понятием ОЗУ).
А память может быть реализована, как угодно (ОЗУ, ПЗУ, магнитная лента, ферритовые сердечники), это C++ не касается.
Ну хорошо память. Просто память.
Сложно сказать что-то глупее:
кроме того ссылка может ссылаться не только на объекты в пямяти.
А после фразы
А память может быть реализована, как угодно (ОЗУ, ПЗУ, магнитная лента, ферритовые сердечники), это C++ не касается.
вообще теряется логика рассуждений.
Вот покажи мне ссылку, которая ссылается не на объект в памяти.
Где тут еще одно имя?
char& c = *(new char(0));
Не вижу хоть убей.
Так ты определись ссылка это еще одно имя или что?
Указатель - способ обращения к объекту.
Туманно. Хотелось бы поподробнее.
Не только *, так же и &, и ->.
Ну да, только ты у нас обладаешь правом на истину.
Читаю:
Первое возражение:
Ссылка - это псевдоним, поэтому разговор об адресе в данном контексте неправильный.
И ниже коментарий к char& c = *(char*)0:
Объект типа char, расположенный по адресу 0.
Так разговор об адресе верен или нет? Не понятно.
Неявный указатель и есть ссылка. Само название ссылка, т.е. она ссылается (указывает) на объект, к которому ты можешь обращается через нее. Так же и указатель указывает (ссылается) на объект, к которому ты можешь обращаться через него. Разница только в интерфейсе. Ты же на основании различия интерфейсов пытаешься доказать, неправомерность определения ссылки через указатель.
Выражать сущность "ссылка" через сущность "указатель" в корне неверно, т.к. ссылка никак не соотносится с указателем (поэтому ты и запутываешь следы всякими "неявное", "вытекающее" и т.п.), а совсем даже наоборот - "указатель" выражается через "ссылку":
Указатель - объект, к которому применима операция разыменования, результатом которой является ссылка, которая (см. определение выше) является способом доступа к некоторому объекту.
Всё. Кратко и понятно. Нет никаких "неявных" и "вытекающих".
А что же такое ссылка? Ты вводишь какие-то "псевдонимы", "еще одни имена", и еще что-то, а четкого определения так и нет.
Ссылка - это объект который представлен указателем и при обращении к которму происходит разименование этого указателя. Что позволяет получить доступ к некоторому объекту.
В C, из которого позаимствованы указатели, ссылок нет и в помине, однако ж там есть разыменование. Как же так, ведь ссылка первична по отношению к указателю, как ты утверждаешь.
У человека есть имя, а есть паспорт.
Имя - сущность нематериальная, а паспорт - это объект.
Некорректно выражать понятие "имя" через понятие "паспорт", что ты пытаешься делать:
"Имя - это неявный паспорт с автоматическим прочтением"
а на самом то деле, это паспорт - документ (объект) содержащий имя человека (объекта).
Дурацкая метафора.
Паспорт идентифицирует не имя, а человека (ведь кроме имени в паспорте есть и фотография, и дата рождения). Так же как и имя идетифицирует человека (но не так полно как паспорт). Так что метафора в корне не верна.
Неявный казатель - это объект который представлен указателем и при обращении к которму происходит разименование этого указателя. Что позволяет получить доступ к некоторому объекту без применения операции разыменовывания (*,->,...) и без получения адреса при инициализации (&).
{
*c = 'A'; // Явно разыменовываем.
}
void func2(char& c)
{
c = 'A'; // Неявно разыминовываем
}
Насколько я понимаю, теоретически эти две функции не делают одно и тоже – одинаковым будет только результат. То есть в первом случае в функции будет создана дополнительная переменная-указатель и затем уничтожена, а во втором никакой дополнительной переменной создано не будет – вся работа будет произведена непосредственно с переменной, передаваемой в функцию?
Если так, то теоретически эффективнее использовать вторую функцию. Иначе, зачем ссылки нужны, если от их использования нет никакой выгоды?
Механизм достижения результат одинков - это запись по переданному адресу значения.
В плане производительности никакой выгоды, однако выгода в краткости кода.
int* p = &x;
int& r = x;
// Тут ниже любой код, который использует r.
Так вот покажи мне случай (приведи фрагмент кода), когда нельзя заменить r на (*p)? Кроме декларирования и инициализации p и r, разумеется.
Для тех, кто в танке:
*p - это операция разыменования, результатом которой является ссылка. С этим спорить будешь?
Ты предлагаешь мне показать случай, когда ссылку нельзя заменить ссылкой?
Нет такого случая.
Только вот, *p - это не ссылка (как ты пытался утверждяать), а ОПЕРАЦИЯ результатом которой является ссылка.
Т.е. ты не понимаешь то что пытаешься опровергнуть? :D
Раз тебе не понятна фраза "ссылка это неявный указатель", зачем ее сразу опровергать?
Я не опровергаю твой мистический "неявный указатель" (хотя и критикую дурацкое определение), мои опровержения касательны твоих утверждений, что ссылка оперирует адресами, что ссылка это по сути указатель, только очень странный и что ссылка введена для сокращения записи работы с указателем (вот это вообще бред).
Обоснуй.
Обоснуй.
Потыкай. Ты меня уже тычешь несколько страниц, но вот только все сводиться к сравнению указетлей и ссылок, хотя при чем тут это - так и не понятно.
Тыкаю (раз ты в не состоянии сам до этого дойт даже после подсказки):
{
A* operator& () {
cout << "A::operator&" << endl;
return 0;
}
};
A c;
A& f = c;
&r; // вот так его можно получить, щупай наздоровье. ;)
Полюбуйся и пощупай.
И рекомендую изучить C++ прежде, чем пытаться спорить.
Покажи когда не является.
T* p = NULL;
Вот покажи мне ссылку, которая ссылается не на объект в памяти.
Да уж раза три показывал:
const int& r = 5;
Где тут еще одно имя?
char& c = *(new char(0));
Не вижу хоть убей.
c - это имя.
Так ты определись ссылка это еще одно имя или что?
См. опроеделение выше, там все написано.
Указатель - способ обращения к объекту.
Нет! Указатель не способ обращения к объекту, для обращения необходимо разыменовать указатель и получить т.о. ссылку.
Не только *, так же и &, и ->.
Ну ты сам то понимаешь, что это бред?
Вводить сущность ради того, чтоб сократить запись на один символ.
Суть ссылки иная, поэтому ссылка в отличие от указателя не является полноценным объектом.
Ну да, только ты у нас обладаешь правом на истину.
Просто я обладаю большей экспертизой, вот и все.
Читаю:
Первое возражение:
Ссылка - это псевдоним, поэтому разговор об адресе в данном контексте неправильный.
И ниже коментарий к char& c = *(char*)0:
Объект типа char, расположенный по адресу 0.
Так разговор об адресе верен или нет? Не понятно.
Объект лежит по адресу и все на этом об адресе забываем.
Ссылка не имеет никакого отношения к адресу, она просто ссылается на объект, при этом не оперирует адресом, она ничего не знает об адресе, не содержит его, не оперирует им.
Неявный указатель и есть ссылка. Само название ссылка, т.е. она ссылается (указывает) на объект, к которому ты можешь обращается через нее. Так же и указатель указывает (ссылается) на объект, к которому ты можешь обращаться через него. Разница только в интерфейсе. Ты же на основании различия интерфейсов пытаешься доказать, неправомерность определения ссылки через указатель.
Ссылается и указывает - это разные вещи.
Я тебе показывал и другие кардинальные отличия ссылки и указателя. Так что не только на основании интерфейса, но ты только что-то только заметил слово "интерфейс".
А что же такое ссылка? Ты вводишь какие-то "псевдонимы", "еще одни имена", и еще что-то, а четкого определения так и нет.
Оно есть постом выше. Читай.
Ссылка - это объект который представлен указателем и при обращении к которму происходит разименование этого указателя. Что позволяет получить доступ к некоторому объекту.
Если ссылка - это объект, значит пока жи мне адрес по которому этот объект расположен, его размер, покажи, какие операции можно выполнять с этим объектом, какое значение имеет этот объект?
В C, из которого позаимствованы указатели, ссылок нет и в помине, однако ж там есть разыменование. Как же так, ведь ссылка первична по отношению к указателю, как ты утверждаешь.
Да мне пофиг, что есть в C, это другой язык программирования.
Сейчас речь идет о C++.
Дурацкая метафора.
Паспорт идентифицирует не имя, а человека (ведь кроме имени в паспорте есть и фотография, и дата рождения). Так же как и имя идетифицирует человека (но не так полно как паспорт). Так что метафора в корне не верна.
Метафора как раз таки очень верна. И ты сам это сейчас подтвердил.
Указатель идентифицирует не имя, а человека, но через имя в нем записанное (забудь про фотографию и дату рождения, а то ты сейчас и семейное положение приплетешь.)
Т.о. паспорт - это объект, физическая сущность.
А вот имя - это не физическая сущность.
Имен у человека может быть много и какое из них первое, какое второе - неважно.
Неявный казатель - это объект который представлен указателем и при обращении к которму происходит разименование этого указателя. Что позволяет получить доступ к некоторому объекту без применения операции разыменовывания (*,->,...) и без получения адреса при инициализации (&).
Что значит обращение к неявному указателю? Покажи кодом описывающим мещанизм этого обращения (не использование, а сам механизм).
Короче все ясно. Основное твое утверждение, и оно же самое НЕВЕРНОЕ, что ссылка - это всего лишь замена указателя, чтоб не писать *, ->, &.
Но если с остальным можно хоть как-то спорить, то это просто бред. Я неоднократно тебе показывал, что сущность ссылки значительно глубже, а эти звездочки и стрелочки - это такая мелочь.
Ты с этим утверждением, как темнота, которая считает, что главное в компьютере - это монитор, потому, что он показывает картинки.
Насколько я понимаю, теоретически эти две функции не делают одно и тоже – одинаковым будет только результат.
То есть в первом случае в функции будет создана дополнительная переменная-указатель и затем уничтожена, а во втором никакой дополнительной переменной создано не будет – вся работа будет произведена непосредственно с переменной, передаваемой в функцию?
С т.з. С++ в первом случае будет создан полноценный объект-указатель, а во втором тоже будет создана некоторая сущность, но она полноценным объектом не является.
Это с т.з. языка C++.
С т.з. же общепринятой реализации - разницы между случаями нет.
Это для конкретного приведенного примера.
Если же рассматривать общий случай разыменования указателя и обращения по ссылке:
и
r = 'A';
То разница гигантская, т.к. операторы разыменования (operator* и operator-> ) могут быть переопределены.
Если так, то теоретически эффективнее использовать вторую функцию. Иначе, зачем ссылки нужны, если от их использования нет никакой выгоды?
Выгода от сокращения записи - это конечно же ерунда.
Выгода от использования ссылок в том, что они как раз являются псевдонимами объекта, т.е. обращение к ним, это тоже самое, что обращение к самому объекту.
Указатель, же являясь полноценным объектом, требует проверки валидности своего значения.
Другими словами, если запись:
{
c = 'A'; // Неявно разыминовываем
}
Валидна всегда в случае валидности самого ссылаемого объекта, то случай
{
*c = 'A'; // Явно разыменовываем.
}
Требует проверки валидности значения указателя, т.е. по хорошему надо написать:
{
if( valid(c) ) {
*c = 'A'; // Явно разыменовываем.
}
}
где valid(c) в большинстве случаев вырождается в (c != NULL).
Кроме того указатели могут (как уже говорил выше) переопределять логику разыменования, а сл-но управлять доступом к объекту по своему усмотрению.
Поэтому, если, например, необходимо передать объект в функцию, или хранить линк на существующий объект, то это лучше делать через ссылку.
Если же надо реализовать какую-то специфичную логику по доступу к объектам (например, итерироваться по массиву), или же кастомизировать механизм доступа к самому объекту (например, auto_ptr), то здесь необходимы указатели.
Если же рассматривать общий случай разыменования указателя и обращения по ссылке:
и
r = 'A';
То разница гигантская, т.к. операторы разыменования (operator* и operator-> ) могут быть переопределены.
Переопределение операторов * и -> для класса никак не повлияют на работу с указателями_на_класс. А вот переопределить эти операторы для указателей не получится. Единственное, что может повлиять на работу с указателями - это, как я писал в своем посте раньше, переопределение оператора взятия адреса (&).
*p - это операция разыменования, результатом которой является ссылка. С этим спорить будешь?
Я понимаю, что к языку C Вы относитесь с брезгливостью, но все же... Операция разыменования существует и в языке C, в котором, как известно, ссылок нет. Так что же тогда возвращает эта операция в С?