Разница между указателем в C++ и ссылочным типом В C#
в C++ указатель-это указатель на адрес памяти, где хранится другая переменная, а в C# ссылка-это то же самое. В чем разница между этими двумя?
6 ответов
для меня понятие то же самое, или, по крайней мере, намеревался быть таким же,но фактическое использование данного, не.
когда мы говорим о указателях или ссылках, мы говорим о концепции. Эта переменная " указывает "или ее" ссылка " на что-то другое, что хранится где-то еще.
Если я использую эту ссылку, например, путем обновления значения, я фактически обновляю ссылочный объект, объект точки переменной к. Если у меня есть объект, на который ссылаются из двух разных мест, я фактически обновляю одно и то же из обоих мест.
таким образом, концепция может быть связана с вашим адресом в реальном мире, это просто способ ссылаться на другую вещь, и эта ссылка может быть разделена, как и многие люди, имеющие мой адрес.
разница больше в том, как он использовался и что было разрешено языком. Обратите внимание, что детали реализации ссылки или указателя не являются неявными в сама концепция. В 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