Есть ли способ найти адрес ссылки? - PullRequest
57 голосов
/ 23 декабря 2009

Есть ли способ найти адрес ссылки?

Уточнение: адрес самой переменной, а не адрес переменной, с которой она инициализируется.

Ответы [ 10 ]

57 голосов
/ 23 декабря 2009

Ссылки не имеют своих собственных адресов. Хотя ссылки могут быть реализованы как указатели, в этом нет необходимости или гарантии.

C ++ FAQ лучше всего говорит:

В отличие от указателя, если ссылка привязан к объекту, он не может быть «пересаживается» на другой объект. ссылка сама по себе не является объектом (это не имеет идентичности; взяв адрес ссылка дает вам адрес референт; помните: ссылка является его референтом).

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

Ссылка является референтом

34 голосов
/ 23 декабря 2009

NO . Нет способа получить адрес ссылки.
Это связано с тем, что ссылка - это не объект, а псевдоним (это означает, что это другое имя объекта).

int  x = 5;
int& y = x;

std::cout << &x << " : " << &y << "\n";

Это распечатает тот же адрес.
Это потому, что «у» - это просто другое имя (псевдоним) для объекта «х».

20 голосов
/ 23 декабря 2009

Стандарт ISO говорит, что это лучше всего:

Не должно быть ссылок на ссылки, массивов ссылок и указателей на ссылки.

Мне не нравится логика, которую многие люди используют здесь, что вы не можете сделать это, потому что ссылка "не гарантированно будет где-то просто указателем". Точно так же, как int x может быть только регистром процессора без адреса, но волшебным образом становится областью памяти при использовании & x, компилятор все же может иметь возможность разрешить то, что вы хотите.

В прошлом многие компиляторы допускали именно то, что вы просите, например,

int x, y;
int &r = x;
&r = &y; // use address as an lvalue; assign a new referent

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

12 голосов
/ 23 декабря 2009

номер

Как говорит Бьярн Страуструп в TC ++ PL, ссылка может рассматриваться как просто другое имя существующего объекта (объекта или функции). Хотя это не всегда самое точное описание базового низкоуровневого механизма, который реализует ссылки, это очень хорошее описание концепции, которую ссылки должны реализовывать на уровне языка. Неудивительно, что язык не предоставляет средств для получения самого адреса ссылки.

На уровне языка ссылка не гарантируется занимать место в хранилище, и, следовательно, в общем случае он не имеет адреса.

9 голосов
/ 24 апреля 2013

Из другого экземпляра этого же вопроса: $ 8.3.2 / 3 - «Не определено, требует ли ссылка хранения (3.7).».

Таким образом, стандарт C ++ позволяет компилятору / разработчику среды выполнения выбирать, находится ли ссылка в отдельном месте памяти. Однако обратите внимание, что если он действительно находится в отдельной области памяти, вы не можете найти его адрес стандартным образом. Так что не делай этого.

Если вы берете адрес ссылки, по определению в стандарте C ++, вы получите адрес того, на что он ссылается, а не адрес ссылки, если на самом деле эта ссылка даже существует как отдельная сущность в среда выполнения или нет.

7 голосов
/ 23 декабря 2009

Просто используйте оператор «&». например:

int x = 3;
int &y = x;
cout<<&y<<endl;

Это вернет адрес x, так как y является не чем иным, как адресом x.

4 голосов
/ 23 декабря 2009

Ненадежно, поскольку ссылки не должны иметь уникального местоположения в адресуемой памяти.

2 голосов
/ 23 декабря 2009

Не само по себе. Если вы хотите его «адрес», поместите его в структуру или класс. Даже тогда это не обязательно гарантирует, что вы окажетесь в непосредственной близости от того, что вы, вероятно, хотите сделать, используя указатель. Если вы хотите подтверждение, размер ссылки равен типу референта. Попробуйте это с char & и посмотрите.

1 голос
/ 08 ноября 2017

Возможно, но не строго с использованием C ++. Поскольку ссылка передается как параметр функции, ее значение будет храниться в стеке или в регистре. Это зависит от аппаратной архитектуры. Для доступа к этим значениям потребуется встроенная сборка. Обратитесь к справочному руководству для процессора, который вы используете для определения поведения стека и регистрации адресов. Повреждение стека или регистров может очень легко вызвать BSOD, потерю данных или даже необратимое повреждение вашей системы. Действуйте с особой осторожностью.

0 голосов
/ 22 апреля 2019
//YES reference varies
//but a little trick in the compiler

    int i = 333;
    int j = 444;
    int &ref = i;                   //ref=i value
    int* p = nullptr;


    printf("ref=%d\n", ref);        //333  i value

    *(&p + 3) = &j;                 //&ref=j

    printf("ref=%d\n", ref);        //444  j value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...