В параметре функции:
- Если параметр не нужно модифицировать, то передаём по константной ссылке
const T&
- Если к тому же параметр -- это POD размером не более 32 байт, то можно передать по значению
T
- Если параметр нужно модифицировать, то передаём по неконстантной ссылке
T&
- Если параметр может отсутствовать (nullptr), то передаём по указателю
T*
/ const T*
. Константность зависит от того, надо ли параметр модифицировать
- Если нужно скопировать внутрь текущего объекта параметр шаблонного типа, то используем универсальную ссылку
T&&
В возвращаемом значении:
- Если нужно вернуть результат, вычисленный в функции, возвращаем значение
- Если нужно вернуть указатель на фиксированную область памяти, возвращаем ссылку / указатель. Различие в использовании и константность подробно описаны выше
- Если мы хотим передать владение, возвращаем
std::unique_ptr
В поле класса:
- Почти всегда по значению
- Указатель указывает на память, которой мы не владеем (не имеем права делать delete). Ссылки нельзя использовать ввиду технических ограничений
std::unique_ptr
указывает на память, которой мы владеем. Предпочитать значению его следует, если это полиморфный тип
Замечание 1. Есть типы, перемещение которых дорого или невозможно: большой
std::array
,
std::fstream
. Если мы хотим передавать владельца переменной такого типа или, например, вернуть из функции, то придётся использовать
std::unique_ptr
.
Замечание 2. "Нужно модифицировать" означает, что мы хотим, чтобы изменения объекта были видны вне функции. Можно и нужно обходиться константной ссылкой, если допустимо скопировать переменную и модифицировать её внутри функции.