Как ссылка C++ выглядит, мудрой памятью?

Другой от xkcd Exploits of a Mom

41
задан Yuval Adam 24 July 2009 в 20:15
поделиться

7 ответов

везде, где встречается ссылка j , она заменяется на адрес i . Таким образом, в основном адрес ссылочного содержимого разрешается во время компиляции, и нет необходимости разыменовывать его, как указатель, во время выполнения.

Просто чтобы прояснить, что я имею в виду под адресом i :

void function(int& x)
{
    x = 10;
}

int main()
{
    int i = 5;
    int& j = i;

    function(j);
}

В приведенный выше код, j не должен занимать место в основном стеке , но ссылка x на функцию займет место в его стеке . Это означает, что при вызове функции с j в качестве аргумента адрес i , который будет помещен в стек функции . Компилятор может и не должен резервировать место в основном стеке для j . и нет указателей на ссылки.

Почему массивы ссылок недопустимы?

48
ответ дан 27 November 2019 в 00:12
поделиться

Как выглядит ссылка на C ++, по памяти?

Нет. Стандарт C ++ говорит только о том, как он должен себя вести, но не о том, как это должно быть реализовано.

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

Помните, что единственное требование для ссылки - это то, что она ведет себя как псевдоним для объекта, на который указывает ссылка. Поэтому, если компилятор встречает этот код:

int i = 42;
int& j = i;
int k = 44;

он видит не «создание указателя на переменную i » (хотя в некоторых случаях компилятор может реализовать его именно так), а скорее «отметьте в таблице символов, что j теперь является псевдонимом для i

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

Что касается создания массива ссылок, вы можете не делайте этого, потому что это было бы бесполезно и бессмысленно.

Когда вы создаете массив, все элементы создаются по умолчанию. Что означает создание ссылки по умолчанию? На что это указывает? Весь смысл в ссылках заключается в том, что они повторно инициализированы для ссылки на другой объект, после чего они не могут быть повторно установлены.

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

он действительно должен поменять его местами и использовать вместо него i .

Что касается создания массива ссылок, вы не можете этого сделать, потому что это было бы бесполезно и бессмысленно.

Когда вы создаете array, все элементы построены по умолчанию. Что означает создание ссылки по умолчанию? На что это указывает? Весь смысл в ссылках заключается в том, что они повторно инициализированы для ссылки на другой объект, после чего они не могут быть повторно установлены.

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

он действительно должен поменять его местами и использовать вместо него i .

Что касается создания массива ссылок, вы не можете этого сделать, потому что это было бы бесполезно и бессмысленно.

Когда вы создаете array, все элементы построены по умолчанию. Что означает создание ссылки по умолчанию? На что это указывает? Вся суть в ссылках заключается в том, что они повторно инициализированы для ссылки на другой объект, после чего их нельзя переустановить.

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

d быть бесполезным и бессмысленным.

Когда вы создаете массив, все элементы конструируются по умолчанию. Что означает создание ссылки по умолчанию? На что это указывает? Вся суть в ссылках заключается в том, что они повторно инициализированы для ссылки на другой объект, после чего их нельзя переустановить.

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

d быть бесполезным и бессмысленным.

Когда вы создаете массив, все элементы конструируются по умолчанию. Что означает создание ссылки по умолчанию? На что это указывает? Весь смысл в ссылках заключается в том, что они повторно инициализированы для ссылки на другой объект, после чего они не могут быть повторно установлены.

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

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

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

38
ответ дан 27 November 2019 в 00:12
поделиться

Вы не можете определить массив ссылок, потому что нет синтаксиса для их инициализации. C ++ не допускает неинициализированных ссылок. Что касается вашего первого вопроса, компилятор не обязан выделять место для ненужных переменных. Невозможно указать j на другую переменную, поэтому фактически это просто псевдоним для i в области видимости функции, и так компилятор обрабатывает ее.

8
ответ дан 27 November 2019 в 00:12
поделиться

Ссылки фактически не существуют физически до тех пор, пока им не понадобится физическое проявление (т. е. как член агрегата).

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

Я уверен, что кто-то укажет на стандартное предложение, в котором упоминается все это.

3
ответ дан 27 November 2019 в 00:12
поделиться

То, что упоминается только вскользь в другом месте - как заставить компилятор выделить некоторое место в памяти для ссылки:

class HasRef
{
    int &r;

public:
    HasRef(int &n)
        : r(n) { }
};

Это лишает компилятор возможности просто рассматривать его как компиляцию- псевдоним времени (альтернативное имя для того же хранилища).

6
ответ дан 27 November 2019 в 00:12
поделиться

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

9
ответ дан 27 November 2019 в 00:12
поделиться

Это не исправлено - компилятор имеет большую свободу в том, как реализовать ссылку в каждом конкретном случае. Итак, во втором примере он рассматривает j как псевдоним для i, больше ничего не нужно. При передаче параметра ref он также может использовать смещение стека, опять же без накладных расходов. Но в других ситуациях он может использовать указатель.

3
ответ дан 27 November 2019 в 00:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: