изменяла вектор, являющийся ее аргументом. Иначе говоря, мы хотим не копировать его (т.е. передавать по значению), не объявлять с помощью константной ссылки (т.е. передавать по константной ссылке), а просто передать обычную ссылку на вектор.
Рассмотрим ссылки более подробно. Ссылка — это конструкция, позволяющая пользователю объявлять новое имя объекта. Например,
int&
— это ссылка на переменную типа
int
. Это позволяет нам написать следующий код:
int i = 7;
int& r = i; // r — ссылка на переменную i
r = 9; // переменная i становится равной 9
i = 10;
cout << r << ' ' << i << '\n'; // вывод: 10 10
Иначе говоря, любая операция над переменной
r
на самом деле означает операцию над переменной
i
. Ссылки позволяют уменьшить размер выражений. Рассмотрим следующий пример:
vector< vector<double> > v; // вектор векторов чисел типа double
Допустим, нам необходимо сослаться на некоторый элемент
v[f(x)][g(y)]
несколько раз. Очевидно, что выражение
v[f(x)][g(y)]
выглядит слишком громоздко и повторять его несколько раз неудобно. Если бы оно было просто значением, то мы могли бы написать следующий код:
double val = v[f(x)][g(y)]; // val — значение элемента v[f(x)][g(y)]
В таком случае можно было
бы повторно использовать переменную
val
. А что, если нам нужно и читать элемент
v[f(x)][g(y)]
, и присваивать ему значения
v[f(x)][g(y)]
? В этом случае может пригодиться ссылка.
double& var = v[f(x)][g(y)]; // var — ссылка на элемент v[f(x)][g(y)]
Теперь можем как считывать, так и изменять элемент
v[f(x)][g(y)]
с помощью ссылки
var
. Рассмотрим пример.
var = var/2+sqrt(var);
Это ключевое свойство ссылок — оно может служить “аббревиатурой” объекта и использоваться как удобный аргумент. Рассмотрим пример.
// передача по ссылке (функция ссылается на полученную переменную)
int f(int& x)
{
x = x+1;
return x;
}
int main
{
int xx = 0;
cout << f(xx) << endl; // вывод: 1
cout << xx << endl; // вывод: 1; функция f изменяет
// значение xx
int yy = 7;
cout << f(yy) << endl; // вывод: 8
cout << yy << endl; // вывод: 8; функция f изменяет
// значение yy
}
Передачу аргументов по ссылке можно проиллюстрировать следующим образом.
Сравните этот пример с соответствующим примером из раздела 8.5.3.
Совершенно очевидно, что передача по ссылке — очень мощный механизм: функции могут непосредственно оперировать с любым объектом, передаваемым по ссылке. Например, во многих алгоритмах сортировки перестановка двух значений — весьма важная операция. Используя ссылки, можем написать функцию, меняющую местами два числа типа
double
.
void swap(double& d1, double& d2)
{
double temp = d1; // копируем значение d1 в переменную temp
d1 = d2; // копируем значение d2 в переменную d1
d2 = temp; // копируем старое значение d1 в переменную d2