В чем разница между: ручкой, указателем и ссылкой

Как дескриптор отличается от указателя на объект, а также почему мы не можем ссылаться на ссылку?

Ответ 1

Ручка обычно является непрозрачной ссылкой на объект. Тип дескриптора не связан с указанным элементом. Рассмотрим, например, дескриптор файла, возвращенный системным вызовом open(). Тип int, но он представляет запись в таблице открытых файлов. Фактические данные, хранящиеся в таблице, не связаны с int, которые были возвращены open(), освобождая реализацию от необходимости поддерживать совместимость (т.е. фактическая таблица может быть реорганизована прозрачно, не затрагивая код пользователя). Ручки могут использоваться только функциями в том же интерфейсе библиотеки, который может перенаправить дескриптор обратно на фактический объект.

Указатель представляет собой комбинацию адреса в памяти и типа объекта, который находится в этой ячейке памяти. Значение - это адрес, тип указателя указывает компилятору, какие операции могут выполняться с помощью этого указателя, как интерпретировать местоположение памяти. Указатели прозрачны в том, что объект, на который ссылается, имеет конкретный тип, который присутствует в указателе. Обратите внимание, что в некоторых случаях указатель может служить дескриптором (a void* полностью непрозрачен, указатель на пустой интерфейс так же непрозрачен).

Ссылки - это псевдонимы для объекта. Вот почему вы не можете ссылаться на ссылку: вы можете иметь несколько псевдонимов для объекта, но вы не можете иметь псевдоним псевдонима. Как и указатели, набираются ссылки. В некоторых случаях ссылки могут быть реализованы компилятором как указатели, которые автоматически разыгрываются при использовании, а в некоторых других случаях компилятор может иметь ссылки, которые не имеют реального хранилища. Важная часть состоит в том, что они являются псевдонимами для объекта, они должны быть инициализированы объектом и не могут быть повторно использованы для обращения к другому объекту после их инициализации. Когда они инициализируются, все использование ссылки - это использование реального объекта.

Ответ 2

Чтобы задать вопрос, "почему мы не можем ссылаться на ссылку?" означает, что вы не понимаете, что такое ссылка.

Ссылка - это другое имя для объекта; больше ничего. Если у меня есть объект, хранящийся в переменной X, я могу создать переменную Y, которая является ссылкой на этот объект. Они оба говорят об одном и том же объекте, и что именно это означает иметь ссылку на Y? Это не будет отличаться от ссылки на X, потому что все они ссылаются на одно и то же.

"Дескриптор" не имеет определения в отношении языка С++. Вообще говоря, "дескриптор" представляет собой конструкцию некоторой формы, которая представляет собой своего рода ресурс. Вы получаете его из некоторого API, который создает ресурс. Вы вызываете функции, которые берут дескриптор в качестве параметра, чтобы запросить состояние ресурса или изменить его. И когда вы закончите с этим, вы передадите его другой функции API.

Указателем может быть дескриптор. Ссылка может быть ручкой. Объектом может быть дескриптор. Целое число может быть дескриптором. Все зависит от того, что хочет сделать система, которая реализует дескриптор.

Ответ 3

A handle также иногда называют "волшебным печеньем". Его просто значение некоторого непрозрачного типа, идентифицирующего объект. В некоторых случаях он реализован как фактический указатель, поэтому, если вы примените его к указателю на правильный тип, вы можете разыменовать его и работать с тем, что он указывает на.

В других случаях он будет реализован как нечто иное, чем указатель - например, у вас может быть таблица объектов этого типа, а дескриптор - просто индекс в этой таблице. Если вы не знаете базовый адрес таблицы, вы не можете ничего сделать с индексом.

С++ просто говорит, что ссылки на ссылки невозможны. Не так уж много "почему" - если бы они хотели достаточно плохо, они, несомненно, могли бы позволить это (а также массивы ссылок, если на то пошло). Однако было принято решение ограничить ссылки (много), чтобы они сделали.

Ответ 4

Разница заключается в контексте.

Основной смысл дескриптора заключается в том, что он относится к некоторому объекту в очень ограниченном контексте; например. ОС может хранить только 20 файлов, открытых для пользователя или pid. Указатель ссылается на один и тот же объект в контексте "памяти". И ссылка - это "псевдоним" объекта - он относится к объекту в контексте исходного кода; поэтому ссылка на ссылку не существует, поскольку ссылка уже "есть" объект.