Как сделать ссылку на объект c
BestProg
Ссылки на объект класса. Доступ к объекту класса по ссылке. Ссылки как члены данных класса. Примеры
Содержание
1. Как объявляется переменная, которая есть ссылкой на класс? Как объявить ссылку на объект класса?
Ссылка на класс объявляется с помощью символа & . При объявлении переменной, которая есть ссылкой, необходимо сразу ее инициализировать значением объекта, для которого уже выделена память.
Общий вид объявления ссылки на объект класса имеет вид:
- CMyClass – имя класса;
- ref – имя переменной, которая есть ссылкой на объект obj ;
- obj – имя объекта, для которого выделена память.
2. Пример объявления ссылки на объект класса и ее использование
Пусть задан класс CYear , реализующий год. Объявление класса имеет следующий вид:
Использование класса в другом методе
В вышеприведенном коде с помощью символа & объявляется переменная-ссылка c2 на объект класса c1 с помощью следующей строки
Для переменной c1 память уже выделена. Переменные c1 и c2 ссылаются на один и тот же участок памяти (на один и тот же объект).
3. Объявление и использование ссылки на объект класса, доступ к которому осуществляется с помощью неуправляемого ( unmanaged ) указателя. Пример
Если объявить указатель на класс ( * ) и выделить для него память, то на этот участок памяти (объект) можно объявить ссылку.
Нижеследующий пример демонстрирует использование указателя и ссылки на класс CYear, что описывается в п. 2.
4. Пример использования ссылки на объект класса, которая есть членом данных другого класса. Что произойдет, если в классе не инициализировать ссылку на объект?
Ссылка (переменная-ссылка) на объект класса может быть членом данных другого класса. При объявлении переменной-ссылки в классе, эта переменная может быть тут же инициализирована в специально разработанном конструкторе. В этом случае для переменной-ссылки класса память выделяется динамически (см. пример ниже).
В примере ниже демонстрируется применение класса CLine (отрезок), в котором объявляются две ссылки на класс CPoint , который описывает точку на координатной плоскости.
В классе CPoint реализованы следующие члены данных и методы:
- внутренние переменные x , y – координаты точки;
- конструктор по умолчанию;
- методы доступа GetXY() , SetXY() .
В классе CLine объявляются следующие члены данных и методы:
- внутренние переменные-ссылки типа CPoint& (ссылка на объект класса CPoint ) с именами p1 , p2 ;
- конструктор с двумя параметрами, который динамично инициализирует ссылки p1 , p2 при объявлении объекта класса;
- методы доступа GetPoints() , SetPoints() .
Объявление классов CPoint и CLine имеет следующий вид:
Важно: при объявлении ссылки на объект некоторого класса, обязательно нужно инициализировать эти ссылки некоторым значением, например, в специально разработанном конструкторе по умолчанию. Если не указать код инициализации ссылки в конструкторе, то компилятор выдаст ошибку:
В классе CLine осуществляется динамическая инициализация ссылок p1 и p2 с помощью конструктора:
Использование класса CLine в другом методе:
Урок №88. Ссылки
Обновл. 31 Дек 2019 |
До этого момента мы успели рассмотреть два основных типа переменных:
обычные переменные, которые хранят значения напрямую;
указатели, которые хранят адрес другого значения (или null), для доступа к которым выполняется операция разыменования указателя.
Ссылки — это третий базовый тип переменных в C++.
Ссылки
Ссылка — это тип переменной в C++, который работает как псевдоним другого объекта или значения. C++ поддерживает три типа ссылок:
Ссылки на неконстантные значения (обычно их называют просто «ссылки» или «неконстантные ссылки»), которые мы обсудим в этом уроке.
Ссылки на константные значения (обычно их называют «константные ссылки»), которые мы обсудим в следующем уроке.
В C++11 добавлены ссылки r-value, о которых мы поговорим уже в следующих главах.
Ссылка (на неконстантное значение) объявляется с использованием амперсанда (&) между типом данных и именем ссылки:
В этом контексте амперсанд не означает «оператор адреса», он означает «ссылка на».
Ссылки в качестве псевдонимов
Ссылки обычно ведут себя идентично значениям, на которые они ссылаются. В этом смысле ссылка работает как псевдоним объекта, на который она ссылается. Например:
В примере выше ref и value обрабатываются как одно целое. Использование оператора адреса с ссылкой приведёт к возврату адреса значения, на которое ссылается ссылка:
Инициализация ссылок
Ссылки должны быть инициализированы при создании:
В отличие от указателей, которые могут содержать нулевое значение, ссылки нулевыми быть не могут.
Ссылки на неконстантные значения могут быть инициализированы только неконстантными l-values. Они не могут быть инициализированы константными l-values или r-values:
Обратите внимание, во втором случае вы не можете инициализировать неконстантную ссылку константным объектом. В противном случае вы бы могли изменить значение константного объекта через ссылку, что уже является нарушением понятия «константа».
После инициализации изменить объект, на который указывает ссылка — нельзя. Рассмотрим следующий фрагмент кода:
Обратите внимание, во втором стейтменте ( ref = value2; ) выполняется не то, что вы могли бы ожидать! Вместо переприсваивания ref (ссылаться на переменную value2 ), значение из value2 присваивается переменной value1 (на которое и ссылается ref ).
Ссылки в качестве параметров в функциях
Ссылки чаще всего используются в качестве параметров в функциях. В этом контексте ссылка-параметр работает как псевдоним аргумента, и сам аргумент не копируется при передаче в параметр. Это, в свою очередь, улучшает производительность, если аргумент слишком большой или затратный для копирования.
В уроке №82 мы говорили о том, что передача аргумента-указателя в функцию, позволяет функции при разыменовании этого указателя напрямую изменять значение аргумента.
Ссылки работают аналогично. Поскольку ссылка-параметр — это псевдоним аргумента, то функция, использующая ссылку-параметр, может изменять аргумент, переданный ей, также напрямую:
Когда аргумент x передаётся в функцию, то параметр функции ref становится ссылкой на аргумент x . Это позволяет функции изменять значение x непосредственно через ref ! Обратите внимание, переменная x не обязательно должна быть ссылкой.
Совет: Передавайте аргументы в функцию через неконстантные ссылки-параметры, если они должны быть изменены функцией в дальнейшем.
Основным недостатком использования неконстантных ссылок в качестве параметров в функциях является то, что аргумент должен быть неконстантным l-value (т.е. константой или литералом он быть не может). Мы поговорим об этом подробнее (и то, как это обойти) в следующем уроке.
Ссылки как более лёгкий способ доступа к данным
Второе (гораздо менее используемое) применение ссылок заключается в более лёгком способе доступа к вложенным данным. Рассмотрим следующую структуру:
Предположим, что нам нужно работать с полем value1 структуры Something переменной other структуры Other (звучит сложно, но такое также встречается на практике). Обычно доступ к этому полю осуществлялся бы через other.something.value1 . А что, если нам нужно неоднократно получать доступ к этому члену? Код может стать несколько громоздким и беспорядочным. Ссылки же предоставляют более лёгкий способ доступа к данным:
Таким образом, следующие два стейтмента идентичны:
Ссылки позволяют сделать ваш код более чистым и понятным.
Ссылки vs. Указатели
Ссылка — это тот же указатель, который неявно разыменовывается при доступе к значению, на которое он указывает (под капотом ссылки реализованы с помощью указателей). Таким образом, в следующем коде:
*ptr и ref обрабатываются одинаково. Т.е. это одно и то же:
Поскольку ссылки должны быть инициализированы корректными объектами (они не могут быть нулевыми) и не могут быть изменены позже, то они, как правило, безопаснее указателей (так как риск разыменования нулевого указателя отпадает). Однако, они немного ограничены в функциональности, по сравнению с указателями.
Если определённое задание может быть решено с помощью как ссылок, так и указателей, то лучше использовать ссылки. Указатели следует использовать в ситуациях, только когда ссылки недостаточно эффективны (например, при динамическом выделении памяти).
Заключение
Ссылки позволяют определять псевдонимы для других объектов или значений. Ссылки на неконстантные значения могут быть инициализированы только неконстантными l-values. Они не могут быть переприсвоены после инициализации. Ссылки чаще всего используются в качестве параметров в функциях, когда мы хотим изменить значение аргумента или хотим избежать его затратного копирования.
Передача объектов по ссылке или значению в C#
В C# я всегда думал, что непримитивные переменные передаются по ссылке, а примитивные значения-по значению.
таким образом, при передаче в метод любого непримитивного объекта все, что сделано с объектом в методе, повлияет на передаваемый объект. (C# 101 stuff)
однако я заметил, что когда я прохожу систему.Рисунок.Image object, что это, похоже, не так? Если я пройду систему.рисунок.объект image в другой метод и загрузить изображение на этот объект, затем пусть этот метод выходит из области и возвращается к вызывающему методу, что изображение не загружается на исходный объект?
7 ответов
объекты не передаются вообще. По умолчанию, аргумент вычисляется и его стоимостью передается по значению в качестве начального значения параметра вызываемого метода. Теперь важным моментом является то, что значение является ссылкой для ссылочных типов – способом получения объекта (или null). Изменения этого объекта будут видны из вызывающего объекта. Однако изменение значения параметра для ссылки на другой объект будет не будет отображается при использовании pass by value, который по умолчанию используется для все типы.
Если вы хотите использовать pass-by-reference, вы должны использовать out или ref , является ли тип параметра типом значения или ссылочным типом. В этом случае фактически сама переменная передается по ссылке, поэтому параметр использует то же место хранения, что и аргумент , а изменения самого параметра видны абонент.
у меня есть статья, которая идет в гораздо более подробно в этом. В принципе, “пройти по ссылке” не означает то, что вы думаете, что это значит.
еще один пример кода для демонстрации этого:
Я думаю, это яснее, когда вы делаете это так. Я рекомендую скачать LinkPad чтобы проверить такие вещи.
и это должно вывести
WontUpdate
имя: Эгли, фамилия: Бесерра
UpdateImplicitly
имя: Фавио, фамилия: Бесерра
UpdateExplicitly
имя: Фавио, фамилия: Бесерра!–4–>
когда вы проходите в System.Drawing.Image введите object в метод, который вы фактически передаете копию ссылки на этот объект.
поэтому, если внутри этого метода вы загружаете новое изображение, которое вы загружаете, используя новую / скопированную ссылку. Вы не вносите изменений в оригинал.
Как вы передали объект методу?
вы делаете новое внутри этого метода для объекта? Если это так, вы должны использовать ref в способ.
следующая ссылка даст вам лучшую идею.
в Pass by Reference вы добавляете только ” ref ” в параметрах функции и один более того, вы должны объявлять функцию “static” из-за main is static (# public void main(String[] args) )!
принятый ответ звучит немного неправильно и запутанно. Что такое “копия ссылки”?”
Как имеет смысл следующее утверждение?:
” однако изменение значения параметра для ссылки на другой объект не будет видно, когда вы используете pass by value, что является значением по умолчанию для всех типов.”Pass by value не является значением по умолчанию для всех типов.
его пример в его ссылке пытается установить экземпляр объекта в значение null. Объект не удалось установить значение null из-за автоматической сборки мусора. Его нельзя удалить таким образом.
вот статья Microsoft, сравнивающая Java и C#.
“все объекты являются ссылками
ссылочные типы очень похожи на указатели в C++, особенно при установке идентификатора для некоторого нового экземпляра класса. Но при доступе к свойствам или методам этот ссылочный тип, используйте “.”оператор, который аналогичен доступу к экземплярам данных в C++, которые создаются в стеке. Все экземпляры класса создаются в куче с помощью оператора new, но delete не допускается, так как оба языка используют свои собственные схемы сбора мусора, рассмотренные ниже.”
Источники:
https://www.bestprog.net/ru/2018/06/13/references-to-the-class-object-access-to-a-class-object-by-reference-references-as-members-of-class-data-examples_ru/
https://ravesli.com/urok-88-ssylki/
https://askdev.ru/q/peredacha-obektov-po-ssylke-ili-znacheniyu-v-c-11031/