Смешивающие указатели и ссылки в определении функции в С++
У меня есть функция, которая имеет два экземпляра классов в качестве аргументов:
void cookPasta(const Tomato& tomato, const Meat* meat)
{
if (meat != nullptr)
cookPastaWithMeat(tomato, *meat);
else
cookPastaWithoutMeat(tomato);
}
Как показывает функция, всегда требуется экземпляр Tomato
, тогда как Meat
является необязательным и вместо него может быть передан nullptr
. Я делаю это, чтобы функция cookPasta
вызывалась, даже если пользователь никогда не объявлял экземпляр класса Meat
.
Неправильная ли практика смешивания ссылок и указателей в сигнатуре функции?
Ответы
Ответ 1
Единственное, что вы теряете при таком подходе, это возможность передать временный Meat
, поскольку его адрес не может быть выполнен.
Почему бы не использовать перегрузку, просто переименовав cookPastaWithMeat
и cookPastaWithoutMeat
?
void cookPasta(const Tomato& tomato, const Meat& meat);
void cookPasta(const Tomato& tomato);
Ответ 2
Ваша практика хороша
- Вы использовали ключевое слово
const
.
- Передача справки
-
Но второй параметр pointer
может быть немного лучше, используя optional parameter feature
для С++. ознакомьтесь здесь.
void cookPasta(const Tomato& tomato, Meat* meat = nullptr)
{
if (meat != nullptr)
cookPastaWithMeat(tomato, *meat);
else
cookPastaWithoutMeat(tomato);
}
Теперь вызовите одну и ту же функцию в обоих направлениях.
cookPasta(tomato); // meat will default to nullptr
cookPasta(tomato, meat);
Ответ 3
Это хорошая практика, поскольку у вас есть веская причина для этого: указатель может быть nullptr
, тогда как ссылка всегда должна быть передана. Вы используете это элегантно.
Использование const
означает, что функция не может изменять параметры, переданные от вызывающего; это тоже хорошо.