ссылки и указатели
В чем принципиальная разница м\у ссылками и указателями, и когда ссылки использовать предпочтительнее:rolleyes:
*p - это операция разыменования, результатом которой является ссылка. С этим спорить будешь?
Ты предлагаешь мне показать случай, когда ссылку нельзя заменить ссылкой?
Нет такого случая.
Только вот, *p - это не ссылка (как ты пытался утверждяать), а ОПЕРАЦИЯ результатом которой является ссылка.
Понятно значит примеров таких нет. Значит в любом коде r и (*p) взаимозаменимы.
Я понял, что ты считаешь бредом все что не вписывается в твое мировоззрение. Однако кажется ты понял что я хочу сказать.
{
A* operator& () {
cout << "A::operator&" << endl;
return 0;
}
};
A c;
A& f = c;
&r; // вот так его можно получить, щупай наздоровье. ;)
Полюбуйся и пощупай.
И рекомендую изучить C++ прежде, чем пытаться спорить.
Ты не торопись. А то ошибки делаешь.
Так я примеров с указатлями на UDT-объекты не приводил. Ты цепляешься к часностям интерфейса, которые вытекают из автоматического разыменовывания, однако это никак не приближает нас к сути ссылки, а мы кажется об этом говорим.
Этот пример говрорит только о том что у ссылок и указателей различен интерфейс.
Тут есть адрес и он равен 0.
const int& r = 5;
А 5 где у нас находиться?
Повторюсь, где тут ЕЩЕ имя?
Четкого определения не вижу.
Ну если способ обращаения к объекту толковать только как употреление имени ссылки или имени указателя, то тогда ты безусловно прав. Но я думаю в поняти "способ обращения" входит больше.
Вводить сущность ради того, чтоб сократить запись на один символ.
Суть ссылки иная, поэтому ссылка в отличие от указателя не является полноценным объектом.
Вот такой вот странный указатель. :D
Дык, я в этом не сомневаюсь. Мне не понятно почему ссылку нельзя рассматривать как странный вид указателя (твое определение) или неочвидный указатель (мое определение). И указатель и ссылка могут указывать/ссылаться на любой адрес в памяти.
Так правильно или не правильно об адресе говорить? Если не правильно ты мы о нем не говорим, а если правильно то спор не имеет основы.
Вот скажи если ссылка не оперирует адресам, откуда она может знать куда ей обращаться в случае:
char& c = *(new char(0));
Адрес выделяемого объекта на этапе компиляции не известен. Т.е. ссылка полюбому должна "знать" этот адрес, чтобы через нее можно было обратиться к объекту в памяти.
Это уже схоластика какая-то.
Они все сводятся к интрфейсу, т.к. интерфйс определяеи принципы использования и наоборот.
Напиши еще раз жирным шрифтом, а то я не вижу точного объяснения.
Это не возможно из-за свойства автоматического разыменования. Но я могу показать как получить указатель которым представлена ссылка:
int* getPtr(int* R)
{
return R;
}
int* getRefPtr(int& R)
{
return ((int*(*)(int&))(void*)&getPtr)(R);
}
int main()
{
int i;
int* p = &i;
int& r = i;
int* rp = getRefPtr(r);
printf("%08x = %08x\n", p, rp);
return 0;
}
Сейчас речь идет о C++.
Этим примером я показываю что указатели прекрасно себя чувствуют и без ссылок.
Указатель идентифицирует не имя, а человека, но через имя в нем записанное (забудь про фотографию и дату рождения, а то ты сейчас и семейное положение приплетешь.)
Ты считаешь имя уникальным идентификатором человека? :D
А вот имя - это не физическая сущность.
Имен у человека может быть много и какое из них первое, какое второе - неважно.
Ты хочешь сказать что указатель это объект хранящий в себе ссылку? :D
Грубо говоря:
{
o.call();
}
превращается в
{
(*o).call();
}
Хотя можно плясать от обратного:
{
o->call();
}
превращается в
{
o.call();
}
Однако это лишний раз подтверждает что ссылка и указатель имеют нечно общее (а именно адрес). Поэтому я считаю ссылку неявням указателем.
Нет. Ссылки вводились для решения нескольких задач суть которых сводится к минимизации явных операций с адресами (которые осуществляются с помощью указателей) и заменой их на неявные (сслыки).
Все твои доводы основаны на различии интерфейса, не более.
И снова дурацкая метафора.
ЗЫ. Не забудь про определение ссылки.
Указатель, же являясь полноценным объектом, требует проверки валидности своего значения.
если запись:
{
c = 'A'; // Неявно разыминовываем
}
Валидна всегда в случае валидности самого ссылаемого объекта[/QUOTE]
Что такое валидность ссылаемого объекта и почему ее не нужно проверять? Казуистика какая-то.
или
// ..
func2(*ptr); // а если ptr == 0?
Поэтому валидность нужно проверять в любом случае и не важно указатель это или ссылка.
Априори это каша? Почему? А псевдоним это конечно не каша, но вот только потом люди удивляются почему вдруг происходит access violation в функции?
{
i = 0;
}
Определение операторов * и -> в классе делают этот класс указателем.
Примеры: auto_ptr, shared_ptr и т.п.
Я понимаю, что к языку C Вы относитесь с брезгливостью, но все же... Операция разыменования существует и в языке C, в котором, как известно, ссылок нет. Так что же тогда возвращает эта операция в С?
Я не отношусь к C с брезгливостью. Я не владею этим языком так, как C++.
Так что что возвращает операция разыменования - это вопрос к знатокам С.
Но так или иначе не стоит путать языки, даже не смотря на то, что они похожи. У них разная концепция.
Примеры: auto_ptr, shared_ptr и т.п.
То есть Вы хотите сказать, что указатель - это класс, в котором определены операторы * и -> ???
Если я правильно понял - Вы опровергаете мое утверждение
[quote=flat]
Переопределение операторов * и -> для класса никак не повлияют на работу с указателями_на_класс. А вот переопределить эти операторы для указателей не получится. Единственное, что может повлиять на работу с указателями - это, как я писал в своем посте раньше, переопределение оператора взятия адреса (&).
[/quote]
Допустим есть класс:
{
Class & operator*()
{
cout << "Class::operator*";
return *this;
}
};
Неужели Вы считаете, что перегрузка оператора * как-то повлияет на работу с классом через хоть обычные, хоть умные указатели?
будет вызываться auto_ptr<Class>::operator*()
Этот пример говрорит только о том что у ссылок и указателей различен интерфейс.
Этот пример показывает, что невозможно осуществить операцию над ссылкой, т.к. ссылка не объект, все обращения к сылке на самом деле есть обращения к объекту.
В этом примере нет операций с указателями, так что ни о каком различии интерфейсов речи не идет.
М-да... ты уже и примеры не воспринимаешь.
Тут есть адрес и он равен 0.
Нет здесь адреса. В данном случае NULL - это показатель невалидности (пустоты) указателя.
А 5 где у нас находиться?
Нигде. Это просто константное значение.
Повторюсь, где тут ЕЩЕ имя?
с - это ещё имя, еще могут быть другие имена, если их задать.
Четкого определения не вижу.
Ну фигово со зрением значит.
Вот такой вот странный указатель.
Значит, ты так и не знаешь, что такое указатель.
как странный вид указателя (твое определение)
Я вообще не рассматриваю ссылку, как указатель, так что не надо мне приписывать такие дурацкие определения.
И указатель и ссылка могут указывать/ссылаться на любой адрес в памяти.
Ссылка не может ссылаться на адрес. Ссылка ссылается на объект или значение (rvalue).
Указатель так же не может указывать на адрес, указатель указывает на объект. Однако у указателя есть значение (в отличие от ссылки) и это значение является адресом.
Так правильно или не правильно об адресе говорить? Если не правильно ты мы о нем не говорим, а если правильно то спор не имеет основы.
Для ссылки говорить об адресе неправильно.
Вот скажи если ссылка не оперирует адресам, откуда она может знать куда ей обращаться в случае:
char& c = *(new char(0));
Адрес выделяемого объекта на этапе компиляции не известен. Т.е. ссылка полюбому должна "знать" этот адрес, чтобы через нее можно было обратиться к объекту в памяти.
Компиляция - это детали реализации, к языку они никакого отношения не имеют.
Это не возможно из-за свойства автоматического разыменования.
Какое загадочное "автоматическое разыменование" на все то оно дает ответ.
Это невозможно потому, что ссылка изначально - не объект и не имеет ни размера ни положения, хотя имеет область действия.
Но я могу показать как получить указатель которым представлена ссылка:
int* getPtr(int* R)
{
return R;
}
int* getRefPtr(int& R)
{
return ((int*(*)(int&))(void*)&getPtr)(R);
}
int main()
{
int i;
int* p = &i;
int& r = i;
int* rp = getRefPtr(r);
printf("%08x = %08x\n", p, rp);
return 0;
}
М-да... наворотил ты. Кстати, void* здесь совершенно не нужен.
Но т.к. ты не понимаешь что такое ссылка, то ты автоматом получаешь ошибку в своих рассуждениях.
Как только ты попытался применить ссылку, ты на самом деле обратился к объекту.
Это вытекает даже из твоего собственного определения с неявным разыменованием.
(R) - вот это будет "неявным разыменованием" по твоей нотации.
int* (int&) - а этот вызов создаст новую ссылку, в твоей нотации - неявный указатель.
А далее ты воспользовался брешью компилятора, который позволил тебе реализацию ссылки (а реализация - частный случай) представить, как реализацию указателя.
Твой пример можно было бы записать значительно проще:
int* p;
__asm mov eax, r
__asm mov rp, eax
Только вот ты не получил значения ссылки, т.к. у ссылки нет значения, а получил реализацию ссылки. С таким успехом можно const char привести к указателю на виртуальный метод класса. Только вот есть ли смысл такого приведения?
Этим примером я показываю что указатели прекрасно себя чувствуют и без ссылок.
Таким примером? Из другого языка программирования?
Класс...
Давай возмем C#, Java, Python и убедимся, что ссылки отлично живут без указателей. :)
Ты считаешь имя уникальным идентификатором человека? :D
Ты считаешь, что метафора - это догма? :D
Ты хочешь сказать что указатель это объект хранящий в себе ссылку? :D
Я уже сказал на счет указателя, что операция разыменования указателя возвращает ссылку. Что указатель хранит, это его личное дело.
Однако это лишний раз подтверждает что ссылка и указатель имеют нечно общее (а именно адрес). Поэтому я считаю ссылку неявням указателем.
Ссылка не имеет адреса. Ссылка вообще внутри себя ничего не имеет.
Нет. Ссылки вводились для решения нескольких задач суть которых сводится к минимизации явных операций с адресами (которые осуществляются с помощью указателей) и заменой их на неявные (сслыки).
Неа, ссылки вводились, как псевдонимы объектов.
Все твои доводы основаны на различии интерфейса, не более.
Да это ты так считаешь.
ЗЫ. Не забудь про определение ссылки.
[QUOTE=Green]
Ссылка - способ обращения к объекту. Именованная ссылка - способ обращения по имени, т.е. псевдоним.
ссылка не имеет ничего собственного (даже размера и адреса), с самого своего рождения ссылается на один единственный объект, все обращения перенаправляет на него, и т.о. является всего лишь псевдонимом этого объекта.
[/QUOTE]
P.S. Ты кажется опять пропустил мой вопрос:
Что значит обращение к неявному указателю? Покажи кодом описывающим механизм этого обращения (не использование, а сам механизм).
Не забудь.
Объект может быть разрушен (частично или полностью) или до конца не создан в момент обращения к нему.
В этом случае он невалиден и проверить это без доп. механизмов невозможно.
или
// ..
func2(*ptr); // а если ptr == 0?
Поэтому валидность нужно проверять в любом случае и не важно указатель это или ссылка.
В данном случае ты показываешь невалидность указателя (общепринято, что 0 - это "пустой" указатель).
Это тип, в котором определены...
Т.е. все верно за исключением того, что "класс" я бы заменил более общим понятием - "тип".
Если я правильно понял - Вы опровергаете мое утверждение
Допустим есть класс:
{
Class & operator*()
{
cout << "Class::operator*";
return *this;
}
};
Неужели Вы считаете, что перегрузка оператора * как-то повлияет на работу с классом через хоть обычные, хоть умные указатели?
будет вызываться auto_ptr<Class>::operator*()
Ты опять не понял.
Я говори про определение этих операторов не в классе объекта, на который указывают, а в классе указателя. Смотри определение выше:
указатель - это тип, для которого (в котором) определены операторы * и ->.
В данном случае Class - это и есть класс указателя.
Ты запутал пример тем, что Class - указывает на тип Class, т.е. на объект собственного же типа.
Я исправлю твой пример, чтоб ты понял:
{
Pointer(Class* pObj) :_pObj(pObj) {}
Class& operator*()
{
cout << "Pointer::operator*";
return _pObj;
}
Class* _pObj;
};
Это примитивный пример, т.к. класс Pointer не добавляет никакой новой функциональности (но, кстати, ограничивает её) к обычному указателю на тип Class.
Однако, более сложные указатели это делают, например, auto_ptr, shared_ptr и т.п.
{
Pointer(Class* pObj) :_pObj(pObj) {}
Class& operator*()
{
cout << "Pointer::operator*";
return [color=red]*[/color]_pObj;
}
Class* _pObj;
};
Пример - безусловно вырожденный случай. :) Как правило используются или обычные указатели, или уже написанные (auto_ptr, например).
Но допустим это, как теоретически возможное. :) Но все же выше речь шла в первую очередь об обычных указателях. Попробуйте, перегрузите ;)
Но, безусловно, это все детали. Я конечно абсолючтно согласен, что ссылки и указатели - это концептуально разные понятия. Я просто согласен с Nixus, что механизм ссылок реализован посредством механизма указателей. Это также подтверждает сишное разыменование. Хотя опять же абсолютно согласен с Вами, в том что не следует циклиться на деталях низкоуровневой реализации. :)
Так же неправильно аргументировать сущность ссылок примерами из C. Это концептуально разные языки. И то что считалось допустимым (хотя не всегда верным) в С не является нормальным в С++. И хотя C++ был создан когда-то на базе C сейчас это дргой язык. И по сути совместимость с классическим поведением в С эмулируется средствами С++, а не наоборот С++ является насдстройкой над С средствами С. )
Не возможно??? Ссылки описанны в стандарте языка - это собственно описание языка по которому должны строится реализации.
Там нет ни слова про адрес. Ни про указатели как реализацию ссыкли.
Как правило используются или обычные указатели, или уже написанные (auto_ptr, например).
Нет, почему же. Использование (и создание различных) smart pointer-ов очень распространенная практика.
Я просто согласен с Nixus, что механизм ссылок реализован посредством механизма указателей.
Тогда возникает вопрос: что такое механизм указателей?
Это также подтверждает сишное разыменование.
Согласись, что утверждать что-то для одного языка программирования, ссылаясь на другой - это некорректно. Странно было бы видеть утверждение о языке C++ на основании положения вещей в языке Haskell или Lua.
Схожесть синтаксиса языков C и C++ и их историческая связь вводит тебя в заблуждение. На самом деле это два разных языка с разными концепциями (парадигмами). Ты же не станешь утверждать, что "механизм ссылок в C# реализован посредством механизма указателей, это подтверждается сишным разыменованием" ?
Почему же невозможно?
Просто ты сосредоточился на том, что ссылка содержит адрес (что совершенно не верно), поэтому не можешь принять других определений.
Как уже сказал aks, в стандарте ссылка описана без использования слова "адрес" или "указатель".
Я привел тебе определение ссылки не используя слово "адрес" или указатель.
Но понятно, я для тебя не авторитет, тогда, может Б.Страуструп тебя убедит:
[QUOTE=Б.Страуструп]
2.3.10 Ссылки
Ссылку можно рассматривать как еще одно имя объекта.
[/QUOTE]
А вот, что тебя вводит в заблуждение:
[QUOTE=Б.Страуструп]
Очевидной реализацией ссылки может служить постоянный указатель, который используется только для косвенного обращения. Тогда инициализация ссылки будет тривиальной, если в качестве инициализатора указан адрес.
[/QUOTE]
Я специально выделил слова "реализация" и "может", т.к. может быть и иная реализация.
В этом примере нет операций с указателями, так что ни о каком различии интерфейсов речи не идет.
М-да... ты уже и примеры не воспринимаешь.
Почему не воспринимаю?
В твоем примере опрератор применяется сначала к ссылке, а потом к объекту на который ссылатеся ссылка. Это происходит неявно. В C++ очень много неявных вещей. Например, неявное преобразование типа.
Ты же не будешь утверждать, что A теперь содержит значение типа char?
При чем тут значение адреса и его интерпретация при программировании?
Ты что-то путаешь. В некоторых системах это вполне нормальный адрес и по нему можно обращаться. Напрмер в реальном режиме процессора x86.
Значение не может быть "нигде".
Хорошо. Если ты утверждаешь что оператор разыменование указателя возвращает ссылку, а сылка это всего лишь имя, то где у нас хоть одно имя тут?
Помоги мне слепому увидеть.
Приведу-ка и я метафору:
"Бритва" и "бритва Оккама" - это совершенно разные вещи. Ты пытаешься показать, что нельзя принцип называть "бритвой Оккама", т.к. бритва - это предмет для бритья.
Детский сад, ей богу.
А я не утверждаю что ты ее так рассматриваешь. Ты так назвал мое виденье данного вопроса.
И указатель указывает на объект или rvalue. Однако он указывает это посредством адреса. Так же и ссылка.
У указателя ты можешь оперировать этим значением, а у ссылки нет.
Различие интерфейса только и всего. Может больше не будем ссылаться на различие интерфейса?
Тогда как определить на что ссылается эта ссылка без упоминания адреса?
char& c = *(char*)1;
Ты опять уходишь в сторону. Как сылка будет знать куда ей обращаться без знания (читай хранения) адреса?
Псевдоним или еще одно имя куда загадочнее.
Так ссылка это объект или неполноценный объект? Ты уж определись.
Но т.к. ты не понимаешь что такое ссылка, то ты автоматом получаешь ошибку в своих рассуждениях.
Т.к. ты не можешь дат четкого определения понятия ссылка, то твои рассуждения вообще лишены смысла.
Что значит применить ссылку?
(R) - вот это будет "неявным разыменованием" по твоей нотации.
int* (int&) - а этот вызов создаст новую ссылку, в твоей нотации - неявный указатель.
Да новая ссылка, однако это позволило получить тот же самый адрес. Я мог написать и вот так:
int* getPtr(int* R)
{
return R;
}
int main()
{
int i;
int* p = &i;
printf("%08x = %08x\n", p, ((int*(*)(int&))(void*)&getPtr)(i));
return 0;
}
Тут создается всего одна ссылка. Как это меняет суть?
Я использую брешь C++. :)
Т.е. различие в том, что ты не хочешь называть то, что мы получили "значением", а называешь мистическим "реализация"...
Класс...
Давай возмем C#, Java, Python и убедимся, что ссылки отлично живут без указателей.
Поэтому говорить что разыменование указателя возвращает ссылку - не верно.
Я считаю что метафоры не должны высасываться из пальца.
Повторюсь. Если операция разыменования указателя возвращает ссылку, а ссылка это псевдоним или еще одно имя, то где найти имя вот здесь?
Откуда такое категоричное заявление? Если интерфейс не позволяет получить содержимое объекта, это не значит, что объект в себе ничего не содержит.
Это твое личное мнение, не ты же проектировал C++. :)
Отличный довод. И не поспоришь даже. :)
Ведь все что я говорю это только мое мнение, и все что ты говоришь - это твое мнение.
Что значит обращение к неявному указателю? Покажи кодом описывающим механизм этого обращения (не использование, а сам механизм).
Не забудь.
Как тебе показать? На пальцах?
Я уже сказал что средствами C++ это не возможно. Сказал несколько раз.
Просто ты сосредоточился на том, что ссылка содержит адрес (что совершенно не верно), поэтому не можешь принять других определений.
Как уже сказал aks, в стандарте ссылка описана без использования слова "адрес" или "указатель"
Где оно это определение? Где? Ну покажи уж наконец, не томи.
Ключевое выделено жирным. Ты же уперся что ссылка является еще одним именем. Разницу чувствуешь?
Покажи, где у него написано что ссылка это только другое имя объекта и ничего более.
Я специально выделил слова "реализация" и "может", т.к. может быть и иная реализация.
Ты телепат? Откуда ты знаешь что меня вводит в заблуждение?
При чем тут значение адреса и его интерпретация при программировании?
Ты что-то путаешь. В некоторых системах это вполне нормальный адрес и по нему можно обращаться. Напрмер в реальном режиме процессора
Да блин че ты привязался к конкретным адресам и конкетному железу? Ты что всегда пишешь на С++ код который будет работать только на x86 и непереносим на другое железо?
С++ ВЫСОКОУРОВНЕВЫЙ язык. Он абстрагирован от этого всего. И позволяет программисту исспользуя его тоже абстрагироваться от этих низкоуровневых вещей. NULL так же абстрактное значения указателя. Чему оно там равно - не важно, это должно быть скрыто от программста. И пользоваться тем, что где то он равен константе 0 - плохо.
Я думаю постить сюда длинные цитаты из стандарта не очень уместно. Могу сказать тебе главы стандарта в которых описываются ссылки в С++, если это устроит. )
NULL - абстрактное значения указателя??? Такого слова, к Вашему сведению, вообще нет в языке (ни в С, ни в С++). В С++, в отличие от С, принято использовать именно константу 0, а не NULL.
"Абстрактное значение указателя" - такого определения нет.
Есть определения null pointer, null pointer value и null pointer constant.
И это не адрес, это отдельный специально выделенный случай.
Есть определения null pointer, null pointer value и null pointer constant.
И это не адрес, это отдельный специально выделенный случай.
Я имел ввиду слово NULL.
Устроит. Я жду. :)
Есть определения null pointer, null pointer value и null pointer constant.
И это не адрес, это отдельный специально выделенный случай.
Это специально выделеный случай значения адреса, который храниться в указателе. :)
В твоем примере опрератор применяется сначала к ссылке, а потом к объекту на который ссылатеся ссылка. Это происходит неявно.
Значит выполняется две операции?
Каков результат первой операции? Каков - второй?
В C++ очень много неявных вещей. Например, неявное преобразование типа.
Все неявные опеации описаны стандартом.
"Неявного разыменование неявного указателя" там нет.
При чем тут значение адреса и его интерпретация при программировании?
Ты что-то путаешь. В некоторых системах это вполне нормальный адрес и по нему можно обращаться. Напрмер в реальном режиме процессора x86.
null pointer value или null pointer constant - это специальное значение и специальный указатель, а не "вполне нормальный адрес". Значение этой константы не оговорено, поэтому обычно применяется макрос NULL.
Хорошо. Если ты утверждаешь что оператор разыменование указателя возвращает ссылку, а сылка это всего лишь имя, то где у нас хоть одно имя тут?
Ссылка - способ доступа к объекту. Именнованная ссылка- псевдоним.
Здесь неименнованная ссылка.
Приведу-ка и я метафору:
"Бритва" и "бритва Оккама" - это совершенно разные вещи. Ты пытаешься показать, что нельзя принцип называть "бритвой Оккама", т.к. бритва - это предмет для бритья.
Детский сад, ей богу.
Если с бритвой "бритва Оккама" нельзя выполнять никаких действий, если бритва "бритва Оккама" не является предметом (объектом), то её нельзя назвать бритвой.
Единственной, что её связывает с понятием "бритва" - это только слово "бритва".
Но у "ссылки" и "указателя" нет даже одинаковых слов.
И указатель указывает на объект или rvalue. Однако он указывает это посредством адреса. Так же и ссылка.
Покажи мне указатель, который указывает на rvalue.
Различие интерфейса только и всего. Может больше не будем ссылаться на различие интерфейса?
Я утверждаю, что это не различие интерфейса, а концептуальное различие.
Тогда как определить на что ссылается эта ссылка без упоминания адреса?
char& c = *(char*)1;
На объект типа char, если 1 - это не null pointer constant. В противном случае - undefined behavior.
Ты согласен с тае, что ссылка не требует хранения?
Т.е. не обязана быть представлена как-то физически, расположена где-то в памяти или ином хранилище?
Ты опять уходишь в сторону. Как сылка будет знать куда ей обращаться без знания (читай хранения) адреса?
Я как раз остаюсь в рамкаъ C++, а ты скатываешься до частных деталей реализации.
Так ссылка это объект или неполноценный объект? Ты уж определись.
Неполноценный объект, я это утверждал с самого начала.
Что значит применить ссылку?
Указал имя ссылки, применил какие-либо операции, т.е. попытался обратиться.
Да новая ссылка, однако это позволило получить тот же самый адрес. Я мог написать и вот так:
<skip>
Тут создается всего одна ссылка. Как это меняет суть?
Суть остается та же - ты оперируешь деталями реализации, которые к языку не имеют отношения.
Таким же образом можно "доказать", что все транспортные средства имеют колеса.
[QUOTE=Green]
А далее ты воспользовался брешью компилятора, который позволил тебе реализацию ссылки (а реализация - частный случай) представить, как реализацию указателя.
Я использую брешь C++. :)
[/QUOTE]
Еще одна твоя явная проблема - ты не видишь различия между определением и частной реализацией.
Компилятор - это не язык C++.
Т.е. различие в том, что ты не хочешь называть то, что мы получили "значением", а называешь мистическим "реализация"...
Нет, различие в том, что ссылка в языке не имеет (в контексте "не содержит") значения, но она как-то должна быть представлена на уровне исполняемого кода. Одно из таких представлений - ато адресс. См. цитату Страуструпа в посте выше.
Поэтому говорить что разыменование указателя возвращает ссылку - не верно.
А я не опираюсь на другие языки в своем утверждении, я опираюсь на синтаксис записи оператора разыменования в языке C++. Так что я опять же не выхожу за рамки этого языка.
Повторюсь. Если операция разыменования указателя возвращает ссылку, а ссылка это псевдоним или еще одно имя, то где найти имя вот здесь?
Именная ссылка - псевдоним, неименная (представленная в примере) - лишь способ доступа.
Откуда такое категоричное заявление?
Из знания языка C++.
Это твое личное мнение, не ты же проектировал C++. :)
Ну так и "неявный указатель" - плод твоего воображения :)
4.10.1
A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type.
Покажи мне здесь слово "адрес".
И обрати внимание на выделенную фразу.
Ну и "контрольный в голову":
3.9.2.3
A valid value of an object pointer type represents either the address of a byte in memory (1.7) or a null pointer (4.10).
Солва нет, слова мои. А суть есть. )
Каков результат первой операции? Каков - второй?
Грубо говоря:
"Неявного разыменование неявного указателя" там нет.
Зато там есть обращение через ссылку на ссылаемый объект. Мы обращаемся сначала к ссылке, а у потом уже к ссылаемому объекту.
Так ты не путай адрес на который указывает указатель и то, чем указатель инициализируется. Указатель всегда указывает на адрес.
1. Литерал - это не объект. Это способ представления объекта в программе. И ссыка ссылается на объект, а не литерал.
2. Любые данные, любой программы хранятся в памяти, не важно как эта память представлена.
Здесь неименнованная ссылка.
Так что такое ссылка? То это мистический "псевдоним", то мистическое "другое имя", а теперь еще более мистичнеский "способ доступа к объекту". Чем дальше, тем непонятнее.
Единственной, что её связывает с понятием "бритва" - это только слово "бритва".
Но у "ссылки" и "указателя" нет даже одинаковых слов.
Бритва - указатель.
Бритва Оккама - неявный указатель.
Принцип - ссылка.
А теперь сравни с цепью своих рассуждений про то что ссылка не может быть неявным указателем, т.к. ссылка и указатель это разные вещи.
Хорошо, давай определимся что такое концептуальное различие и чем оно отличается от различия в интерфейсе? Я уже писал что принципы использования и интерфейс вещи не отдилимые друг от друга.
Что за объект? Откуда он взялся?
Это не частные детали реализации, а общие детали реализации. Или некоторых архитектурах мы будем использовать неполноценный C++?
Ты прыгал с "не объекта", на "неполноценный объект".
Какие там были операции? :)
Таким же образом можно "доказать", что все транспортные средства имеют колеса.
Не очень понятно.
Компилятор - это не язык C++.
Так я пока не вижу того самого определения без привязки к реализации, о котором ты тут толкуешь.
Смотрел, откомментировал.
Из синтаксиса оператора разыменования следует, что он возвращает ссылку? Какой бред!
Что за мистический "способ доступа"?
Остальную часть абзаца ты не смог откомментировать?
"Ты не прав потому что я знаю C++ лучше тебя" - вот и все твои аргументы.
Тебе не нравиться само определение ссылки как неявного указателя. При чем тут мое воображение? Ссылка существует и в твоем воображении.
ЗЫ. Я не буду более продолжать дискуссию пока не будет представленно точного полного определения ссылки.
Так значит в твоем примере:
char& f = c;
&r; // вот так его можно получить, щупай наздоровье. ;)
&r - создает и возвращает указатель на объект, что же ты тогда мне выдаешь это за "значение указателя, который эта ссылка неявно представляет" ?
Это значение вновь созданного указателя.
Зато там есть обращение через ссылку на ссылаемый объект. Мы обращаемся сначала к ссылке, а у потом уже к ссылаемому объекту.
Покажи где там (в стандарте) описана такая схема.
Так ты не путай адрес на который указывает указатель и то, чем указатель инициализируется. Указатель всегда указывает на адрес.
А ты не путай "значение указателя" и куда указатель "указывает".
Указатель не всегда "указывает на адрес". Конкретное место из стандарта я тебе показал.
Так что такое ссылка? То это мистический "псевдоним", то мистическое "другое имя", а теперь еще более мистичнеский "способ доступа к объекту". Чем дальше, тем непонятнее.
"способ доступа" фигурирует в моем определении уже не один пост. Вернись и прочти.
Бритва - указатель.
Бритва Оккама - неявный указатель.
Принцип - ссылка.
А теперь сравни с цепью своих рассуждений про то что ссылка не может быть неявным указателем, т.к. ссылка и указатель это разные вещи.
Что то я не понял, почему это "Бритва Оккама" - неявный указатель, куда указывает этот указатель?
Бритва - указатель.
Бритва Оккама - квазинестабильный синусоидальный передефакт.
Принцип - ссылка.
А теперь сравни с цепью своих рассуждений про то что ссылка не может быть квазинестабильным синусоидальным передефактом.
[QUOTE=Green]
Покажи мне указатель, который указывает на rvalue.
[/QUOTE]
Ты показал мне указатель инициализированный значением (rvalue), а я просил указатель, указывающий на rvalue.
Для того, чтоб отличать rvalue, разберись: http://www.rsdn.ru/article/cpp/lvalue.xml
Хорошо, давай определимся что такое концептуальное различие и чем оно отличается от различия в интерфейсе? Я уже писал что принципы использования и интерфейс вещи не отдилимые друг от друга.
Давай. Что общего у ссылки и указателя?
Я правильно тебя понимаю, что ссылка - это частный случай указателя?
Тогда что ссылка переняла от указателя?
У тебя проблема с классификацией.
Имя, ссылка и указатель предоставляют доступ к объекту, но из этого не следует, что ссылка происходит (является частным случаем указателя).
Так круг и квадрат - это фигуры, однако эта общность не делает квадрат частным случаем круга.
/ | \
имя ссылка указатель
но не
|
указатель
|
ссылка
Что за объект? Откуда он взялся?
Да не важно. Когда ты ссылаешься на кого-либо, ты же не поясняешь откуда он взялся. :D
Это не частные детали реализации, а общие детали реализации. Или некоторых архитектурах мы будем использовать неполноценный C++?
Я как раз таки использую "полноценный C++" без деталей каких-либо реализаций.
А ты затачиваешься именно на детали реализаций, т.е. не на общие вещи, а на частности.
Какие там были операции? :)
Ну хотя бы твое мистическое неявное разыменование. :)
Из синтаксиса оператора разыменования следует, что он возвращает ссылку? Какой бред!
Что возвращает эта функция: int f(); ?
Из синтаксиса получается, что значение типа int. Какой бред? :D
"Ты не прав потому что я знаю C++ лучше тебя" - вот и все твои аргументы.
Я понимаю твое представление ссылки. Я не согласен, как с определением, т.к. оно очень туманно и не дает четкого представления, что такое ссылка (по нему я не могу определить, что я могу делать со ссылкой, как мне отличить ссылку от других типов и чем же она отличается от др. типов). И я не согласен с твоим представлением, т.к. ссылка имеет только одно общее с указателем - она предоставляет доступ к объекту. Обычное имя переменной, кстати, тоже предоставляет доступ к объекту, и ссылка здесь больше схожа с именем переменной, чем с указателем.
Ты же даже не можешь понять моего представления ссылки (причем, другие понимают), но упорно утверждаешь, что оно неверно.
Тебе не нравиться само определение ссылки как неявного указателя.
Не нравится.
При чем тут мое воображение?
При том, что "неявный указатель" - плод твоего воображения.
ЗЫ. Я не буду более продолжать дискуссию пока не будет представленно точного полного определения ссылки.
Да и хрен с тобой. Определение не раз фигурировало выше, не вижу смысла повторяться.
P.S. Ты то сам как считаешь, ты привел хоть одно "точное и полное определение"?
Фраги с другими зарабатывайте.
Фраги с другими зарабатывайте.
Определение тебе было показано не раз. Ты просто не в состоянии его осмыслить, зациклившись на "неявных указателях".
Я вот твое представление понимаю и могу точно указать, что в нем неверно:
Ссылка не является частным случаем указателя, т.к. не обладает НИКАКИМИ свойствами указателя.
Кстати, как на счет твоего определения? Ты сам то можешь привести "Полное и точное определение" ?
Предлагаю тему резюмировать - если у кого есть предложения по существу - добавить, и тему закрыть.
http://www.parashift.com/c++-faq-lite/references.html
[quote=Marshall Cline]
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object. It is not a pointer to the object, nor a copy of the object. It is the object.
[/quote]
http://discuss.fogcreek.com/joelonsoftware2/default.asp?cmd=show&ixPost=63717&ixReplies=46
[quote=David Jones]
A reference is not a pointer.
If you take the address of something (i.e. create a pointer), then the compiler must allocate that object to memory, e.g. on the stack. It cannot keep the value in a register.
If you initialize a C++ reference with something, then a smart optimizing/inlining compiler can deduce that the something can still be contained in a register. Many compilers will implement references as pointers, especially if debugging is enabled, but that's an implementation issue.
David Jones
Wednesday, August 13, 2003
[/quote]
http://www.ubookcase.com/book/Addison.Wesley/Cpp.Gotchas/0321125185_ch01lev1sec5.html
[quote=Stephen C. Dewhurst]
Gotcha #5: Misunderstanding References
There are two common problems with references. First, they're often confused with pointers. Second, they're underused. Many current uses of pointers in C++ are really C holdovers that should be ceded to references.
A reference is not a pointer. A reference is an alias for its initializer. Essentially, the only thing one can do with a reference is initialize it. After that, it's simply another way of referring to its initializer. (But see Gotcha #44.) A reference doesn't have an address, and it's even possible that it might not occupy any storage:[/quote]
IMHO из этих цитат ясно видно, что ссылка - это не указатель, ни обычный, ни мистический "неявный".
Так же из цитат видно, что заблуждения, которым подвергнут Nixus типичны.
И вот ещё одна интересная ссылка о различиях между ссылками и указателями:
http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29#Relationship_to_pointers
Если у вас нет определения ссылки (не способов интерпретации ссылки, а именно определения), то закругляемся.
Как же не заявить в конце, что это мы не смогли дать определения, а не ты не можешь врубиться (или признать) вещи, которые разжевали и в рот положили.
М-да... даже сторонние источники для тебя не катят.
Ты сам себе источник абсолютный истины.
Тогда спорить, действительно сложно.
Вот только одного я не пойму.
Ты выразил непонятный термин "ссылка", через еще более непонятный термин "неявный указатель"
указатель != неявный указатель
Из серии "неявный баг != баг", "неявное воровство != воровство" ("не пойман - не вор")...
Т.е. "неявный указатель" - это не указатель вовсе.
Зачем тогда использовать слово "указатель" в словосочетании "неявный указатель" ?
Использовал бы любое другое слово, например "фиговина".
Это этого твое определение только выиграло бы:
"Ссылка - это неявная фиговина"
нет слова "указатель" вводящего в заблуждение, и уж сразу понятно, что фиговина - это не указатель. Тогда и выражение твое смотриться логично:
"указатель != неявная фиговина"
P.S. Ты кстати, по английски читаешь? Может, ты просто не понял суть цитат, которые я привел?
Как же не заявить в конце, что это мы не смогли дать определения, а не ты не можешь врубиться (или признать) вещи, которые разжевали и в рот положили.
Не нужно думать, что ты знаешь какие мотивы движут мной в этой дисскусии.
Ты сам себе источник абсолютный истины.
Тогда спорить, действительно сложно.
Мдя. Для тех кто в танке:
Ссылка это не указатель. Я с этим сгласен и не спорю.
Все твои доказательства основываются на этом постулате, с которым я согласен. И сторонние исчтоники пишут тоже самое.
Однако, ссылку я называю неявным указателем т.к. ссылку можно полно определить только через адрес объекта, на который она ссылается. С понятием адреса, кроме ссылки, в C++ оперирует только указатель. Но только явным образом. Поэтому ссылка это неявный указатель.
Если у вас нет определения ссылки (не способов интерпретации ссылки, а именно определения), то закругляемся.
Какие блин определения? Есть только то как описывается ссылка в стандарте языка. Все - это первично и отсюда надо плясать.
Я кстати обещал сказать в каких параграфах стандарта читать, но забыл. Теперь только завтра. Хотя впринципе можешь и по содержанию сам поглядеть. ))
Однако, ссылку я называю неявным указателем т.к. ссылку можно полно определить только через адрес объекта, на который она ссылается. С понятием адреса, кроме ссылки, в C++ оперирует только указатель. Но только явным образом. Поэтому ссылка это неявный указатель.
Кто тебе сказал, что ссылку можно определить только через адрес? Что значит полно определить? Переопределить стандарт? Где в стандарте написанно про адрес в ссылке? Мне нагенерить идей реализации ссылок не исспользующих адрес объекта? Фантазии хватит, противоречить не будет языку. ))
Блин уже которую страницу пытаются донести одно - нельзя по конкретной реализации в каком то режиме компилятора судить об этой сущности во всем языке и таким образом расспространять на все возможные реализации. )
Кто тебе сказал, что ссылку можно определить только через адрес?
Какая разница кто сказал. Ты мне покажи как ее определить иначе, а потом возражай.
Так я не тороплюсь - подожду. Ты главное пришли место в стандарте где она определена.
Дать такое определение чтобы оно могло дать объяснение на что ссылается ссылка для всех случаях ее инициализации.
Вот несколько из них:
char& c = *(char*)0;
char& c = *(char*)1;
char& c = *(new char);
И если мы говорим что разыменование указателя возвращает ссылку (это Green так утверждает), то дать опеределение что же такое ссылка здесь:
Как только ты дашь определение, которое охватывает все эти примеры. Я буду считать определение полным.
Блин уже которую страницу пытаются донести одно - нельзя по конкретной реализации в каком то режиме компилятора судить об этой сущности во всем языке и таким образом расспространять на все возможные реализации. )
Где ты увидел слово реализация? Адрес, в общем случае, это обозначение ячейки памяти.
ЗЫ. С нетерпением жду идей генерации ссылки без адреса. :)
И если мы говорим что разыменование указателя возвращает ссылку (это Green так утверждает), то дать опеределение что же такое ссылка здесь:
Ты сомневаешься, что здесь возвращается ссылка?
Как только ты дашь определение, которое охватывает все эти примеры. Я буду считать определение полным.
Ссылка - способ доступа к объекту.
Указатель это тоже способ доступа к объекту, значит указатель это ссылка? Тут явное противоречие. :)
Тут возвращается lvalue, согласно стандарту.
См. 5.3.1:
Заметь "T", а не "reference to T" или "T&".
Мдя. Для тех кто в танке:
Ссылка это не указатель.
Я с этим сгласен и не спорю.
Однако, ссылку я называю неявным указателем т.к. ссылку можно полно определить только через адрес объекта, на который она ссылается. С понятием адреса, кроме ссылки, в C++ оперирует только указатель. Но только явным образом. Поэтому ссылка это неявный указатель.
прикольно. на украине в таких случаях говорят: "Не вмер Данило, а болячка задавила" (Не умер Данило, а болезнь задавила).
Стандарт 2003 года, глава 8 и в частности 8.3.2. - ссылки. Четвертая часть говорит достаточно четко - не может быть ссылки на ссылку, массива ссылок и указателя на ссылку. Достаточно странно для указателя - даже неявного, не правда ли?
Что общего у ссылки с указателем? Достаточно мало. Ссылка - это действительно только псевдоним, и то что и указатель и ссылка работают с адресами в памяти, указатель и ссылка не могут быть созданны непосредственно для битового поля - но это не делает их похожими - основное различие - указатель имеет собственный адрес - ссылка нет. Поэтому вы можете сколь угодно придумывать себе терминов - явные указатели, неявные указатели, вы в праве пойти по пути госпожи Блавадской и посторить свой - неявный - стандарт языка - но только в таком случае предупреждайте честно - что это вы придумали сами.