Разница между указателем в C++ и ссылочным типом В C#

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

6 ответов


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


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

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

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

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

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

ссылка является ссылкой и, будучи так, это просто не имеет смысла суммировать две ссылки, или добавить один в ссылку ... что бы это значило? Я не могу добавить два домашних адреса (например, Baker Street + Home Street) ...

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

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

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


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


Это разные звери. В 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# не учитывает ссылки. Вместо этого он поддерживает список доступности - к чему можно получить доступ через все открытые указатели, которые у нас есть. То, что не может, утилизируется. Такой подход является более безопасным, но имеет ряд недостатков с точки зрения предсказуемости результатов.


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

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

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

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


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