2015-01-12 7 views
2

Хотя существуют дваллион источников для разъяснения концепции ссылок на C++, я пытаюсь объяснить концепцию ссылки на кого-то, кто знаком с указателями. Другими словами, мне интересно, верно ли следующее семантическое выражение ALLWAYS?Справочная семантика в C++

TYPE& == *(TYPE const *) 
+0

Что значит ВСЕГДА? –

+0

@PranitKothari при любых обстоятельствах и в любых ситуациях. –

+3

Это не везде * рядом * ВСЕГДА эквивалент. Во-первых, разыменовывает const-указатель на объект const, * не * совместим с неконстантной ссылкой, поэтому он даже не * юридический *. Почему вы решили ввести «const» в это? – WhozCraig

ответ

0

Да, если разобрать C++ код в Visual Studio, ссылка не что иное, как const pointer. Таким образом, оба они почти эквивалентны.

Но имейте в виду, что вы не можете назначить NULL (0/nullptr).

+3

Примечание: псевдоним OP не является указателем 'const'; это указатель на 'const'. Существует большая разница. Первый запрещает модификацию * указателя *. Последний запрещает модификацию * объекта *, на который указывает. – WhozCraig

+0

@WhozCraig, spot on, OP, вероятно, хочет 'TYPE & == * (TYPE * const)', но даже в этом случае ссылки на самом деле не такие, как этот ответ указывает: невозможно инициализировать с помощью NULL ссылку, но можно инициализировать to NULL - указатель 'const'. – vsoftco

+0

Выход одного компилятора (или, действительно, все) не является окончательным для языкового вопроса. –

0

Возможно, лучший способ объяснить ссылки - использовать пример Stroustroup, показывающий, как они позволяют создавать функции, которые заменяют макросы, что было бы невозможно без ссылок.

+0

Пожалуйста, ссылайтесь на пример. –

+0

Это в его печатной книге. Насколько я помню, ссылки были включены в C++, чтобы покончить с макросами, которые изменили параметр. – user3344003

+0

Были добавлены ссылки для поддержки перегрузки оператора. –

0

Заявленная возможный типа эквивалентность TYPE& == *(TYPE const *) не имеет буквальный смысл, так как правая рука не тип, а поскольку речь идет о указателе на const вместо const указателя.

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

T& r = o; 

перезаписывается в

T* const __p = &o; 

и где каждое использование r затем переписано как

(*__p) 

За исключением обработки c ase, где o - выражение rvalue, которое объясняет большинство и, возможно, все практические свойства ссылок.

Однако, как соответствующие FAQ item “How can you reseat a reference to make it refer to a different object?” государств,

пожалуйста, не путайте ссылки с указателями; они очень отличаются от точки зрения программиста

+0

: «case, где' o' - выражение rvalue », вы имеете в виду продление срока жизни для временных рядов? –

+0

@BenVoigt: Точно. Также проблема принятия адреса 'o' тогда, но так как мы находимся под капотом формальных правил, которые можно отмахивать руками. –

0

Один из способов это отличается, в том, что вы не можете взять адрес ссылки,
, но вы можете взять адрес указателя. Так как вы можете взять указатель
, он должен иметь память. Однако ссылки не должны иметь хранилища
(они определены в стандарте как псевдонимы), и, как часто может компилятор,
они фактически не имеют хранилища.

+0

Применение адреса оператора к ссылке и к результату использования '*' на указателе имеет точно такой же эффект - адрес цели. Обе ссылки и указатели нуждаются в равном количестве хранилища, поскольку они содержат одинаковое количество информации, пока компилятор не сможет доказать, что информация может быть получена другими способами, а затем не требуется никакого хранения. –

+0

Как только компилятор попадает на низкоуровневый код, он больше не заботится о разнице между ссылками и указателями. Если компилятор может опустить пробел указателя без изменения поведения, ему это разрешено. –

0

Выражение

TYPE& == *(TYPE const *) 

выглядит немного ошибок домена, как TYPE& является типом в то время как *(TYPE const*) выглядит как выражение применяется к типу. По крайней мере, правая сторона должна быть указателем const, а не указателем на const, т.е.:

A TYPE& ведет себя как авто-разыменовываются неизменным указатель, что-то вроде *(TYPE* const) с неявным ограничением, что указатель не может быть пустым.

Компилятор делает распознает ссылки, а в некоторых случаях, а именно, когда связывающий временные переменные в качестве ссылки на const объекта (T const&) в области видимости функции: срок времени временного получает расширяется до тех пор, ссылка не выходит из области видимости ! Например:

{ 
    std::string const& s = std::string("longer lived"); 
    // the original temporary created above still lives 
} // <-- ... and gets destroyed when s goes out of scope here 

Еще одно важное различие между указателями и ссылками являются семантика, когда речь идет о перегрузкой операторов: указатели рассмотрим встроенные типы и операторы с участием только встроенные типы не могут быть перегружены. Ссылка типа T& ведет себя как объект T, то есть перегруженные операторы для T&. То есть, хотя a T& идентичен использованию T* const с точки зрения представления, компилятор понимает разницу и рассматривает объекты по-разному на семантическом уровне.

Смежные вопросы