Ссылки

Последнее обновление: 25.02.2023

Ссылка (reference) представляет способ манипулировать каким-либо объектом. Фактически ссылка - это альтернативное имя для объекта. Для определения ссылки применяется знак амперсанда &:

int number {5};
int &refNumber {number};

В данном случае определена ссылка refNumber, которая ссылается на объект number. При этом в определении ссылки используется тот же тип, который представляет объект, на который ссылка ссылается, то есть в данном случае int.

При этом нельзя просто определить ссылку:

int &refNumber;

Она обязательно должна указывать на какой-нибудь объект.

Также нельзя присвоить ссылке литеральное значение, например, число:

int &refNumber = 10;

После установления ссылки мы можем через нее манипулировать самим объектом, на который она ссылается:

#include <iostream>

int main()
{
	int number {5};
    int &refNumber {number};
	std::cout << refNumber << std::endl; // 5
	refNumber = 20;
	std::cout << number << std::endl; 	// 20
}

Изменения по ссылке неизбежно скажутся и на том объекте, на который ссылается ссылка.

Можно определять не только ссылки на переменные, но и ссылки на константы. Но при этом ссылка сама должна быть константной:

const int number{5};
const int &refNumber{number};
std::cout << refNumber << std::endl; // 5
//refNumber = 20; 		изменять значение по ссылке нельзя

Инициализировать неконстантную ссылку константным объектом мы не можем:

const int number {5};
int &refNumber {number}; // ошибка

Также константная ссылка может указывать и на обычную переменную, только значение по такой ссылке мы не сможем изменить:

int number {5};
const int &refNumber {number};
std::cout << refNumber << std::endl; // 5

//refNumber = 20; 		изменять значение по ссылке на константу нельзя
	
// но мы можем изменить саму переменную
number = 20;
std::cout << refNumber << std::endl; 	// 20

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

ссылки в цикле for

В большинстве случае ссылки находят свое применение в функциях, когда надо передать значения по ссылке, что будет рассмотрено в последующих статьях. Однако есть и другие сценарии использования ссылок. Например, в цикл for, который перебирает последовательность в стиле "for-each", мы не можем изменить значения перебираемых элементов. Например:

#include <iostream>

int main()
{
    int numbers[] {1, 2, 3, 4, 5};
    // меняем число на его квадрат
    for (auto n : numbers)
    {
        n = n * n;
    }
    // смотрим результат
    for (auto n : numbers)
    {
        std::cout << n << "\t";
    }
    std::cout << std::endl;
}

Здесь два цикла. В первом цикле при переборе массива помещаем каждый элемент массива в переменную n и изменяем ее значение на квадрат числа. Однако это приведет только к изменению этой переменной n, но никак не элементов перебираемого массива numbers. Элементы массива сохранят свои значения, что нам и покажет второй цикл, который выводит элементы на консоль:

1       2       3       4       5

Теперь используем ссылки:

#include <iostream>

int main()
{
    int numbers[] {1, 2, 3, 4, 5};
    // теперь n - ссылка на элемент массива
    for (auto& n : numbers)
    {
        n = n * n;
    }
    // смотрим результат
    for (auto n : numbers)
    {
        std::cout << n << "\t";
    }
    std::cout << std::endl;
}

Теперь в первом цикле переменная n представляет ссылку на элемент массива. Использование ссылки позволяет оптимизировать работу с циклом, поскольку теперь значение элемента массива не копируется в переменную n. И через ссылку можно изменить значение соответствующего элемента:

1       4       9       16      25

Иногда, наоборот, не нужно или даже нежелательно изменять элементы коллекции. В этом случае мы можем сделать ссылку константной:

#include <iostream>

int main()
{
    int numbers[] {1, 2, 3, 4, 5};
    // n - константная ссылка
    for (const auto& n : numbers)
    {
        std::cout << n << "\t";
    }
    std::cout << std::endl;
}

Хотя здесь мы не можем изменять значение элемента, но также с помощью ссылок оптимизируем перебор массива, так как элементы массива не копируются в переменную n.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850