Чтение онлайн

на главную - закладки

Жанры

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

}

Поскольку в функцию передается копия, инструкция

x=x+1
в функции
f
не изменяет значения переменных
xx
и
yy
, передаваемых ей при двух вызовах. Передачу аргумента по значению можно проиллюстрировать следующим образом.

Передача по значению представляет собой довольно

простой механизм, а ее стоимость определяется стоимостью копирования значения.

8.5.4. Передача параметров по константной ссылке

Передача по значению проста, понятна и эффективна, если передаются небольшие значения, например переменные типа

int
,
double
или
Token
(см. раздел 6.3.2). А что если передаваемое значение велико и представляет собой изображение (занимающее несколько миллионов бит), большую таблицу чисел (например, несколько тысяч целых чисел) или длинную строку (например, сотни символов)? Тогда копирование оказывается очень затратным механизмом. Не стоит слишком сильно беспокоиться о стоимости выполняемых операций, но делать ненужную работу также не следует, так как это свидетельствует о плохом воплощении идеи, которую мы хотим реализовать. Например, можно написать следующую функцию, выводящую на экран вектор чисел с плавающей точкой:

void print(vector<double> v) // передача по значению; приемлемо ?

{

cout << "{ ";

for (int i = 0; i<v.size; ++i) {

cout << v[i];

if (i!=v.size–1) cout << ", ";

}

cout << " }\n";

}

Функцию

print
можно применять к векторам любых размеров. Рассмотрим пример.

void f(int x)

{

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

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

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

// ...заполняем векторы vd1, vd2, vd3 значениями...

print(vd1);

print(vd2);

print(vd3);

}

Этот код работает, но при первом вызове функции

print
будет скопирован десяток чисел типа
double
(вероятно, 80 байт), при втором — миллионы чисел типа
double
(вероятно, восемь мегабайт), а при третьем количество копируемых чисел неизвестно. Возникает вопрос: “Зачем вообще что-то копировать?” Мы же хотим распечатать вектор, а не скопировать его. Очевидно, нам нужен способ передачи переменных функциям без их копирования. Например, если вы получили задание составить список книг, находящихся в библиотеке, то совершенно не обязательно приносить копии всех книг домой — достаточно взять адрес библиотеки, пойти туда и просмотреть все книги на месте.

Итак, нам необходим способ передачи

функции
print
“адреса” вектора, а не копии вектора. “Адрес” вектора называется ссылкой (reference) и используется следующим образом:

void print(const vector<double>& v) // передача по константной ссылке

{

cout << "{ ";

for (int i = 0; i<v.size; ++i) {

cout << v[i];

if (i!=v.size–1) cout << ", ";

}

cout << " }\n";

}

Символ

&
означает ссылку, а ключевое слово
const
предотвращает случайную модификацию аргумента в функции
print
. Кроме объявления аргумента, все остальное без изменений. Правда, теперь все операции будут производиться не над копией, а над самим аргументом, полученным по ссылке. Такие аргументы называются ссылками, потому что они ссылаются на объекты, определенные вне функции. Вызов функции
print
остается точно таким же, как и раньше.

void f(int x)

{

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

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

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

// ...заполняем векторы vd1, vd2, vd3 значениями...

print(vd1);

print(vd2);

print(vd3);

}

Этот механизм можно проиллюстрировать графически.

Константная ссылка обладает полезным свойством: она не позволяет случайно изменить объект, на который ссылается. Например, если мы сделаем глупую ошибку и попытаемся присвоить элементу вектора, полученного извне функции

print
, какое-то значение, то компилятор сразу выдаст сообщение об этом.

void print(const vector<double>& v) // передача по константной ссылке

{

// ...

v[i] = 7; // ошибка: v — константа (т.е. не может изменяться)

// ...

}

Передача аргументов по константной ссылке — очень полезный и распространенный механизм. Вернемся к функции

my_find
(см. раздел 8.5.1), выполняющей поиск строки в векторе строк. Передача по значению здесь была бы слишком неэффективной.

int my_find(vector<string> vs, string s); // передача по значению:

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

Генерал Империи

Ланцов Михаил Алексеевич
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Генерал Империи

Приручитель женщин-монстров. Том 1

Дорничев Дмитрий
1. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 1

Виконт. Книга 1. Второе рождение

Юллем Евгений
1. Псевдоним `Испанец`
Фантастика:
фэнтези
боевая фантастика
попаданцы
6.67
рейтинг книги
Виконт. Книга 1. Второе рождение

Идеальный мир для Лекаря 25

Сапфир Олег
25. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 25

Магия чистых душ 3

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Магия чистых душ 3

Шипучка для Сухого

Зайцева Мария
Любовные романы:
современные любовные романы
8.29
рейтинг книги
Шипучка для Сухого

Метатель. Книга 2

Тарасов Ник
2. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель. Книга 2

Отмороженный 5.0

Гарцевич Евгений Александрович
5. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 5.0

Кодекс Охотника. Книга XIII

Винокуров Юрий
13. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XIII

Деспот

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Деспот

Огненный князь 6

Машуков Тимур
6. Багряный восход
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Огненный князь 6

Ваше Сиятельство 5

Моури Эрли
5. Ваше Сиятельство
Фантастика:
городское фэнтези
аниме
5.00
рейтинг книги
Ваше Сиятельство 5

"Фантастика 2024-5". Компиляция. Книги 1-25

Лоскутов Александр Александрович
Фантастика 2024. Компиляция
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Фантастика 2024-5. Компиляция. Книги 1-25

Поступь Империи

Ланцов Михаил Алексеевич
7. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Поступь Империи