Подтвердить что ты не робот

Перегрузить метод или использовать значения по умолчанию? С++

Я все еще относительно новичок в С++, и я не могу понять разницу в следующих двух способах кодирования функции, которая может принимать один параметр или, возможно, два или три или более. Во всяком случае, здесь моя точка

перегрузка функции:

int aClass::doSomething(int required)
{
    //DO SOMETHING
}

int aClass::doSomething(int required, int optional)
{
    //DO SOMETHING
}

как это отличается от значения по умолчанию:

int aClass::doSomething(int required, int optional = 0)
{
    //DO SOMETHING
}

Я знаю, что в разных обстоятельствах человек может быть более подходящим, чем другой, но о каких вещах я должен знать при выборе между этими параметрами?

4b9b3361

Ответ 1

Во-первых, вы говорите о перегрузке, а не о переопределении. Переопределение выполняется для функций virtual в производном классе. Перегрузка относится к тому же имени функции с другой сигнатурой.

Разница логична - в первом случае (2 версии) две функции могут вести себя совершенно иначе, тогда как второй случай будет иметь более или менее ту же логику. Это действительно зависит от вас.

Ответ 2

Есть несколько технических причин, чтобы предпочесть перегрузку аргументов по умолчанию, они хорошо изложены в Google Руководство по стилю С++ в Раздел Аргументы по умолчанию:

Указатели функций запутываются при наличии аргументов по умолчанию, поскольку сигнатура функции часто не соответствует сигнатуре вызова. Добавление аргумента по умолчанию к существующей функции меняет свой тип, что может вызвать проблемы с кодом, принимающим его адрес. Добавление функции перегрузки устраняют эти проблемы.

и

параметры по умолчанию могут привести к более громоздкому коду, поскольку они реплицируются на каждом сайте вызова - в отличие от перегруженных функций, где "значение по умолчанию" появляется только в определении функции.

В положительной части говорится:

Часто у вас есть функция, которая использует значения по умолчанию, но иногда вы хотите переопределить значения по умолчанию. Параметры по умолчанию позволяют легко способ сделать это, не определяя многие функции для редких исключения.

Таким образом, ваш выбор будет зависеть от того, насколько важны негативные проблемы для вашего приложения.

Ответ 3

Вы используете функцию перегрузки, если вы предоставляете несколько constructor s. Преимущество в этом случае заключается в том, что вы можете реагировать по-разному в каждом constructor на переданных аргументах. Если это важно, используйте перегрузку.
Если вы можете предоставить достойные default значения для ваших параметров, и это не повлияет на правильность работы вашего кода, используйте параметры по умолчанию.

Смотрите здесь для потока на SO.

Ответ 4

Компилятору все равно, какой из них вы используете. Представьте, что вы написали его как два конструктора, и они закончили примерно 20 строк. Далее представьте, что 19 строк были идентичными, а другая строка читала

foo = 0;

в одной версии и

foo = optional;

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

Теперь представьте себе другую пару конструкторов или функций, которые снова имеют длину около 20 строк, но совершенно разные. Например, вторым параметром является идентификатор, и если он предоставлен, вы смотрите в базу данных, и если вы не устанавливаете значения nullptr, 0 и т.д. У вас может быть значение по умолчанию (-1 для этого популярно), но тогда тело функции будет заполнено

if (ID == -1)
{
    foo = 0;
}
else 
{
    foo = DbLookup(ID);
}

который может быть трудно читать и сделает одну функцию намного длиннее, чем две отдельные функции. Я видел функции с одним гигантским if, который эссенциально разделял всю вещь на два отдельных блока без общего кода, и я видел, что такое же условие протестировало 4 или 5 раз по мере продвижения вычисления. Оба трудно читать.

Это о С++. Есть много способов добиться большинства вещей. Но эти разные способы служат различным целям, и как только вы "получите" тонкие различия, вы напишете лучший код. В этом случае "лучше" означает более короткий, быстрый (все эти if затраты времени исполнения) и более выразительные - люди, читающие его, могут быстро понять ваши намерения.