Смешивающие указатели и ссылки в определении функции в С++

У меня есть функция, которая имеет два экземпляра классов в качестве аргументов:

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 означает, что функция не может изменять параметры, переданные от вызывающего; это тоже хорошо.