Перейти к основному содержимому

Ссылки

Ссылка в С++ — это переменная, хранящая адрес какой-либо другой переменной, но, в отличие от указателя, семантически эквивалентна переменной, на которую она ссылается. Т.е. любые операции над ссылкой на самом деле будут производиться над той переменной, на которую она ссылается. Это касается в том числе операторов sizeof и typeid.

Из-за этого саму ссылку невозможно изменить (её значение задаётся в момент создания и остаётся неизменным) и соответственно объявить без начального значения.

int x = 1;   // integer variable
int* p = &x; // pointer to x
int& r = x; // x reference

x++; // increment x
(*p)++; // increment x using pointer
r++; // increment x using reference

При инициализации можно использовать ключевое слово auto:

auto p = Point{0, 0};

auto c = p; // copy p to c
auto& rp = p; // initializing a reference to Point

Ссылки на массив записываются так:

int a[4];
int(&ra)[4] = a;

А ссылки на функцию так:

void fn(int);
void(&fnRef)(int) = fn;

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

Передача параметра по ссылке

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

#include <iostream>

struct Point {
float x;
float y;
};

void scale(Point& p, float k) {
p.x *= k;
p.y *= k;
}

void print(const Point& p) {
std::cout << "{x: " << p.x << ", y: " << p.y << '}';
}

int main() {
auto point = Point{1, 2};
scale(point, 2);
print(point); // expected "{x: 2, y: 4}"
}

Здесь в обеих функциях параметр p представляет собой "синоним" некоторой переменной типа Point и все операции которые с ним происходят на самом деле применяются к переменной, на которую этот параметр ссылается.

Функция scale используется для изменения объекта на месте, при этом имея более приятный синтаксис по сравнению с передачей указателя в стиле чистого Си.

Функция print использует ссылку для оптимизации копирования. Часто будет полезно обозначить тип как константу (const Type& — ссылка на константу типа Type), чтобы предотвратить изменение переменной, на которую ссылаются.


Источники: