Ссылки определяются как псевдонимы. В стандарте не указывается, как они представлены, хотя реализации не сильно отличаются.По существу:
- В общем случае ссылка, под капотом, адрес объекта (например, указатель)
- Всякий раз, когда это возможно, компилятор будет стремиться устранить Косвенность
Давайте посмотрим, как это переводится, начиная с вашей программы:
int main()
{
int *pi = new int(50);
int &ri = *pi;
ri = 30;
std::cout << "val = " << ri << " , " << *pi << std::endl;
}
Мы E liminate ri
, так как объект он связан, как известно компилятором:
int main()
{
int *pi = new int(50);
*pi = 30;
std::cout << "val = " << *pi << " , " << *pi << std::endl;
}
Мы можем устранить *pi
, потому что ее окончательное значение известно компилятором:
int main() {
new int(50); // stupid possible side effect usually forbid to optimize this out
std::cout << "val = " << 30 << " , " << 30 << std::endl;
}
Я хотел бы отметить, что в вашем Например, вызов new
полностью бесполезен, вы также можете ссылаться на объекты, которые не были динамически распределены.
int main() {
int i = 50;
int& ri = i;
ri = 30;
std::cout << "val = " << ri << " < " << i << std::endl;
}
В равной степени действует и без утечки памяти.
Возвращаясь к нашему различию между представлениями:
void swap(Foo& left, Foo& right);
обычно реализуется как:
void swap(Foo* left, Foo* right);
В этом случае ссылка в конце концов принимает (некоторое) пространство (как как указатель).
С другой стороны, с:
class Object {
public:
Object(): foo(f), f() {}
Foo const& foo;
void set(Foo const& value);
private:
Foo f;
};
Компилятор обычно не дают foo
исполняемая представление. Тот факт, что это ссылка const
, будет использоваться для ограничения возможных методов, вызываемых на f
, тем, кто не меняет его (семантическая разница), но во время выполнения они будут переданы непосредственно f
.
Никакие ссылки не потребляют никакой памяти, и любые изменения, внесенные в переменную или ссылку, отражаются друг к другу. Это единственное, что вам нужно знать. Все, что компилятор заботится, и вам не нужно беспокоиться около. –
Лучше всего рассматривать ссылки как несколько иной синтаксис для указателей. Спецификация ссылок на C++ такова, что, хотя технически это не указатели, вряд ли компилятор мог бы рассматривать их как что-либо, кроме указателей, и по-прежнему быть эффективным. _Небольшая обработка немного отличается, но опять же, только логически, компилятор вряд ли что-то сделает. –