Разница между указателем в C ++ и ссылочным типом в C # - PullRequest
7 голосов
/ 27 января 2010

В C ++ указатель - это указатель на адрес памяти, в котором хранится другая переменная, а в C # ссылка примерно такая же. В чем разница между этими двумя?

Ответы [ 6 ]

9 голосов
/ 27 января 2010

Для меня, концепция - это то же самое , или, по крайней мере, она должна быть такой же, , но фактическое использование не .

Когда мы говорим об указателях или ссылках, мы говорим о концепции. Эта переменная «указывает» или является «ссылкой» на что-то еще, то, что хранится где-то еще.

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

Таким образом, концепция может быть связана с вашим адресом в реальном мире, это просто способ сослаться на другое, и эту ссылку можно передать, как и многие люди, имеющие мой адрес.

Разница больше в том, как оно использовалось и что было разрешено языком. Обратите внимание, что детали реализации ссылки или указателя не подразумеваются в самой концепции. В C # это продолжает быть правдой.

Ссылка - это ссылка, и в таком случае просто не имеет смысла суммировать две ссылки или добавлять одну к ссылке ... что бы это вообще значило? Я не могу добавить два домашних адреса (например, Бейкер-стрит + Домашняя улица) ...

В C ++ деталь реализации ссылки на самом деле является ссылкой. Таким образом, указатель не просто указатель, он также (и используется как) адрес памяти. Таким образом, например, вы можете добавить указатели, потому что на самом деле имеет смысл добавить два адреса памяти для получения другого или добавить 4 к адресу памяти. Таким образом, в C ++ указатель перестал быть концептом и стал именем, данным для фактической реализации .

Вот почему в C # указатели и ссылки - это разные вещи. Поскольку с точки зрения семантики значение очень похоже, они хотели отличить от старой концепции C и C ++, где указатель стал таким же, как адрес памяти.

Я рекомендую вам прочитать статью " Ссылки не являются адресами " от Эрика Липперта , где, как мне кажется, он отлично справляется с объяснением различий.

9 голосов
/ 27 января 2010

В C # ссылочный тип будет автоматически собираться, когда он больше не нужен.

1 голос
/ 27 января 2010

Это разные звери. В C ++ boost :: shared_ptr чем-то похож на C # referenecs, но также является отличным зверем (из этих двух).

Ссылка указывает на объект, который будет утилизирован сборщиком мусора. То же самое происходит в случае shared_ptr. Тем не менее, существует концептуальная разница между тем, как C # и boost :: shared_ptr отслеживают время жизни объекта (см. Ниже).

Указатели C ++ могут указывать на что-либо, размещенное либо в стеке (в этом случае удаление не требуется), статически в куче, либо в выделении чего-либо вручную, по требованию, которое затем должно быть освобождено, и это полностью входит в обязанности программиста ,

Различия между ссылками на shared_ptr и C #:

shared_ptr - счетчик ссылок. Он подсчитывает, сколько клонов вашего указателя существует, и удаляет объект, если его нет. Это не дает решения против перекрестных ссылок (или циклических ссылок ), когда A указывает на B, что указывает на A, но и A, и B больше не нужны.

С этим занимается сборка мусора в C #. C # не считает ссылки. Вместо этого он поддерживает список доступности - к чему можно получить доступ через все открытые указатели, которые у нас есть. Что не может, так и есть. Этот подход более безопасен, но имеет ряд недостатков с точки зрения предсказуемости производительности.

1 голос
/ 27 января 2010

Так называемые ссылки в C # реализуются указателем на указатель на фактический объект. Они называются дескрипторами, и хотя сам дескриптор остается фиксированным в течение всего времени жизни программы, внутренний указатель изменяется по мере перемещения объекта в память сборщиком мусора во время фазы сжатия памяти.

0 голосов
/ 27 января 2010

C ++ - указатель физического уровня, в котором хранится значение физического адреса. C # ссылка скорее это скрытый или непрозрачный указатель, где вы просто знаете, что он указывает на некоторый объект

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

// physical level operation

// set pointer to specific address
byte *pPointer = 0x00LB10;
// increment pointer
pPointer++; 

// OR
// dereference operation for classes and structure
pPointer->MyProperty

В C # вы можете использовать только ссылку (объект ссылочного типа) для доступа к объектам.

MyReference.Property
0 голосов
/ 27 января 2010

Первое отличие состоит в том, что вы не можете использовать арифметику указателей для ссылок. В остальном они практически одинаковые.

  • Обе точки / ссылки на реальный объект.
  • Оба могут иметь значение NULL / null (т.е. не указывать на действительный объект)
  • Оба могут быть назначены новому объекту

Другое отличие состоит в том, что сборщик мусора заботится о выделенных ресурсах в C # .. в C ++, вы должны удалить их самостоятельно (или использовать смарт-указатель).

И затем, конечно ... вам не нужно разыменовывать ссылки вручную в C #, чтобы получить доступ к значению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...