Инициализируйте ссылку, набрав адрес переменной

#c

Вопрос:

Что это такое?
1)

 CCamera amp;MyCamera = *(CCamera *)0xB6F028;
 

Мы получаем адрес переменной: 0xB6F028, вводим его в CCamera* и разыменовываем.
И инициализируйте ссылку CCamera. Что? Как это работает?
Разыменовав, мы получим значение этого адреса. И это значение присваивается ссылке?
2)

 CPool<CVehicle, CHeli> *amp;CPools::ms_pVehiclePool =*(CPool<CVehicle, CHeli> **)0xB74494;  
 

Это у нас есть ссылка COOL на указатель.
И у нас есть адрес указателя для начала этого класса.
Далее мы наберем адрес указателя на указатель на указатель на CPool следующим образом: (CPool**)0xB74494.
А затем мы разыменуем это и получим значение 0xB74494. Это значение — указатель на начальный CPool — это адрес начального CPool в памяти.
Ну, это адреса в памяти: 0xB74494 значение хранилища: 0xAddressOfCPool
Что случилось? Почему мы снова присваиваем значение var ссылке на указатель?
Мы снова присваиваем значение var.

Как это работает?

введите описание изображения здесь

Комментарии:

1. Этот трюк, возможно, вызывает неопределенное поведение (UB), но мне интересно! А может быть, у нас есть книга, в которой описываются эти трюки? Пожалуйста, дайте мне знать

2. (CCamera *) является явным преобразованием типа. Это в значительной степени слово Божье для составителя. Независимо от того, насколько глупо то, что вы собираетесь сделать на самом деле, компилятор позволит это, не задавая вопросов. Это означает, что если у вас нет допустимого CCamera значения 0xB6F028, вам придется удалить <удалено ругательство>, как только вы попытаетесь использовать эту ссылку.

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

4. @user4581301 хорошо, мы наберем этот адрес на указатель. Но почему мы разыменовываем его? Путем разыменования мы получаем значение этого адреса, но почему? Ссылка, инициализированная значением var в памяти?

5. «Разыменование» существует только потому MyCamera , что или ms_pVehiclePool определены как ссылки и не указатели. Ссылка технически является указателем (адресом), но семантика такова, как если бы она была объектом. MyCamera переменная будет содержать адрес 0xB6F028 .

Ответ №1:

Разыменовав, мы получим значение этого адреса. И это значение присваивается ссылке?

Вы не можете назначить ссылку. Вы можете инициализировать только ссылку.

Теперь подумайте об этом:

 int x = 42;
intamp; rx = x; // initialises rx to refer to x
 

Пока все так хорошо? Давайте продолжим.

 intamp; rx = *(amp;x); // still initialises rx to refer to x
                 // because *(amp;x) is exactly the same as just x
 

Никаких проблем с этим? Тогда в чем *(CCamera *)0xB6F028; проблема?

Когда вы разыменовываете указатель, какой результат вы получаете? Понимает ли *(amp;x) тебя 42 ?

Не совсем. Вы получаете значение glvalue. Значение glvalue определяет идентичность объекта. И когда вы инициализируете ссылку значением glvalue, эта ссылка начинает ссылаться на этот объект. Когда вы выполняете большинство других действий с значением glvalue, оно автоматически преобразуется в значение prvalue, которое в данном случае действительно равно 42. Но инициализация ссылки не относится к числу таких вещей.

Так что же происходит, когда вы разыменовываете (CCamera *)0xB6F028; ? Вы получаете значение glvalue, которое является идентификатором объекта, который находится по адресу 0xB6F028 и тип которого CCamera . И вы инициализируете ссылку этим. Таким образом, ссылка теперь относится к объекту, находящемуся по этому адресу.

Если CCamera по этому адресу действительно есть «а», вы молодец. В противном случае попытка разыменования этого указателя будет UB.

 CPool<CVehicle, CHeli> *amp;CPools::ms_pVehiclePool =*(CPool<CVehicle, CHeli> **)0xB74494;  
 

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