Ссылки и const-корректность
Дайте переменной второе имя, а const пусть охраняет ваши намерения
const — и вы получите обещание, которое проверяет компилятор: "я это прочитаю, но не изменю". Вместе ссылки и const позволяют дёшево передавать большие объекты, писать самодокументируемые интерфейсы и ловить целый класс ошибок на этапе компиляции, а не в 3 часа ночи в продакшене.
- объяснить, что такое lvalue-ссылка и чем она отличается от указателя,
- передавать параметры по
const-ссылке, избегая копий и не рискуя изменением, - писать
const-методы и понимать, что они гарантируют, - рассуждать о том, почему const-корректность делает большие программы безопаснее и понятнее.
1. Что такое ссылка на самом деле?
lvalue-ссылка — это имя, которое ссылается на уже существующий объект. Когда вы пишете int& r = x;, вы не создаёте копию x и не создаёте новый объект — вы даёте тому же самому объекту второе имя. С этого момента r и x — две этикетки на одной ячейке памяти.
Ссылку определяют два правила, отделяющие её от любого другого инструмента C++:
- Она обязана быть инициализирована. Неинициализированных ссылок не существует.
int& r;не компилируется — ссылка должна привязаться к чему-то в момент рождения. - Её нельзя переназначить. Раз
rссылается наx, она ссылается наxвсю свою жизнь. Записьr = y;не заставляетrуказывать наy; она копирует значениеyвx.
#include <iostream>
int main() {
int x = 10;
int& r = x; // r - другое имя для x
r = 20; // запись через r -> меняет x
std::cout << x << '\n'; // печатает 20
int y = 99;
r = y; // НЕ переназначение: копирует значение y в x
std::cout << x << '\n'; // печатает 99
std::cout << &r << " == " << &x << '\n'; // тот же адрес
}
Поскольку r и x разделяют один адрес, взятие &r и &x даёт одинаковый указатель. У ссылки нет собственной наблюдаемой памяти — она действительно есть тот же объект под другим именем.