Ссылка или указатель?
И ссылки, и указатели позволяют работать с переменной из другого места, например из функции. Но они отличаются несколькими свойствами:
| Ссылка | Указатель | |
|---|---|---|
| Создание | int& r = x; | int* p = &x; |
| Значение | r, как у обычной переменной | *p |
| Вызов функции | addPoint(score) | addPoint(&score) |
| «Ничего» | невозможно, ссылка всегда принадлежит переменной | nullptr, проверяйте перед использованием |
| Другая переменная | невозможно, ссылка всегда принадлежит одной и той же переменной | p = &y; |
Так что же и когда использовать? Предпочитайте ссылки:
- Функция должна изменить переменную или вектор: ссылка,
int& score,std::vector<int>& scores. - Функция только читает вектор или текст: константная ссылка,
const std::vector<int>& numbers,const std::string& name. - Указатель используйте, только когда вам нужно «ничего» (
nullptr) или перенаправление на другую переменную либо когда этого требует библиотека, которой вы пользуетесь.
Ссылки проще и безопаснее: не нужно писать звёздочки, нельзя забыть & в вызове, а ссылка не может быть nullptr, поэтому её не нужно проверять. Но указатели остаются важными в C++. Они понадобятся в более сложных темах, например когда программа во время работы запрашивает новую память или когда вы строите собственные структуры данных.
Задание
- 1
Программа выводит
Привет!Привет!Привет!, но обе функции без причины используют указатели. Перепишите функциюaddExclamationтак, чтобы она принимала ссылкуstd::string&вместо указателя. Тогда внутри функции не понадобится*, а в вызове —&. - 2
Так же перепишите функцию
repeat. Программа по-прежнему выводитПривет!Привет!Привет!. - 3
Под функцией
repeatнапишите функциюwrapс двумя параметрами типаstd::string:text, который функция меняет, иborder, который она только читает. Выберите способ передачи по правилам выше. Функция добавляет границу в начало и в конец текста. Перед строкой вывода вызовитеwrap(greeting, "**"). Программа выведет**Привет!Привет!Привет!**. Если передать границу по ссылке безconst, компиляция закончится ошибкойno matching function for call to 'wrap': текст в кавычках — не переменная, поэтому обычная ссылка его не принимает.