Ссылки
Ссылка в С++ — это переменная, хранящая адрес какой-либо другой
переменной, но, в отличие от указателя, семантически эквивалентна переменной,
на которую она ссылается. Т.е. любые операции над ссылкой на самом деле будут
производиться над той переменной, на которую она ссылается.
Это касается в том числе операторов 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), чтобы предотвратить изменение переменной, на которую ссылаются.
Источники: