Литмир - Электронная Библиотека
A
A

void g(int x)

{

  vector<double> vd1(10);      // небольшой вектор

  vector<double> vd2(1000000); // большой вектор

  vector<double> vd3(x);       // вектор неопределенного размера

  init(vd1);

  init(vd2);

  init(vd3);

}

Итак, мы хотим, чтобы функция

init()
изменяла вектор, являющийся ее аргументом. Иначе говоря, мы хотим не копировать его (т.е. передавать по значению), не объявлять с помощью константной ссылки (т.е. передавать по константной ссылке), а просто передать обычную ссылку на вектор.

Рассмотрим ссылки более подробно. Ссылка — это конструкция, позволяющая пользователю объявлять новое имя объекта. Например,

int&
— это ссылка на переменную типа
int
. Это позволяет нам написать следующий код:

int i = 7;

int& r = i; // r — ссылка на переменную i

r = 9;      // переменная i становится равной 9 <div class="fb2-image"><!--[litru_binary]_068.png[/litru_binary]--></div>

i = 10;

cout &lt;&lt; r &lt;&lt; ' ' &lt;&lt; i &lt;&lt; '\n'; // вывод: 10 10

Иначе говоря, любая операция над переменной

r
на самом деле означает операцию над переменной
i
. Ссылки позволяют уменьшить размер выражений. Рассмотрим следующий пример:

vector&lt; vector&lt;double&gt; &gt; 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&amp; 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&amp; x)

{

  x = x+1;

  return x;

}

int main()

{

  int xx = 0;

  cout &lt;&lt; f(xx) &lt;&lt; endl;  // вывод: 1

  cout &lt;&lt; xx &lt;&lt; endl;     // вывод: 1; функция f() изменяет

                          // значение xx

  int yy = 7;

  cout &lt;&lt; f(yy) &lt;&lt; endl;  // вывод: 8

  cout &lt;&lt; yy &lt;&lt; endl;     // вывод: 8; функция f() изменяет

                          // значение yy

}

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

Программирование. Принципы и практика использования C++ Исправленное издание - _069.png

Сравните этот пример с соответствующим примером из раздела 8.5.3.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 Совершенно очевидно, что передача по ссылке — очень мощный механизм: функции могут непосредственно оперировать с любым объектом, передаваемым по ссылке. Например, во многих алгоритмах сортировки перестановка двух значений — весьма важная операция. Используя ссылки, можем написать функцию, меняющую местами два числа типа
double
.

void swap(double&amp; d1, double&amp; d2)

{

  double temp = d1; // копируем значение d1 в переменную temp

  d1 = d2;          // копируем значение d2 в переменную d1

  d2 = temp;        // копируем старое значение d1 в переменную d2

}

int main()

{

  double x = 1;

  double y = 2;

  cout &lt;&lt; &quot;x == &quot; &lt;&lt; x &lt;&lt; &quot; y== &quot; &lt;&lt; y &lt;&lt; '\n'; // вывод: x==1 y==2

  swap(x,y);

  cout &lt;&lt; &quot;x == &quot; &lt;&lt; x &lt;&lt; &quot; y== &quot; &lt;&lt; y &lt;&lt; '\n'; // вывод: x==2 y==1

}

В стандартной библиотеке предусмотрена функция

swap()
для любого типа, который можно скопировать, поэтому его можно применять к любому типу. 

8.5.6. Сравнение механизмов передачи параметров по значению и по ссылке

Зачем нужны передачи по значению, по ссылке и по константной ссылке. Для начала рассмотрим один формальный пример.

115
{"b":"847443","o":1}