Ответ Томалака - отличный совет для вызова существующих функций.Когда вы пишете функцию (или когда вы можете изменять ее) и хотите, чтобы параметры были необязательными, вы должны попытаться спроектировать ее так, чтобы использование было правильным, интуитивно понятным и самодокументируемым.Если мы сравним:
1) bool really_test = ...;
test(really_test, my_test);
2) if (...)
test(my_test);
3) test(... ? &my_test : NULL);
2) более понятно для использования if
- универсально понятного ключевого слова, а не просто подразумевает, что первый аргумент функции может быть установлен для обхода теста.Опасный сценарий состоит в том, что кто-то пишет код, подобный 3) неправильное запоминание или неправильное понимание API;он будет работать до тех пор, пока не будет выполнено условие NULL (которое может быть в prod, а не в тестировании).
Аналогично, когда какое-либо поведение является необязательным, я предпочитаю использовать enum для документирования этих опций вместо логического значения, которое сообщаетничего на сайте звонка.Контраст ...
test(false);
test(true);
... с ...
test(Text_Output);
test(Html_Output);
Если имеется несколько аргументов, то может быть полезно использовать часовой, например NULL, для указания того, чтонекоторые из них не применимы.Труднее понять это неправильно, если аргументы имеют различный тип:
test(my_test, /* output stream */ NULL, &error_counter, /* skip list */ NULL);
При таком использовании вы можете ожидать ошибку времени компиляции, если аргумент случайно пропущен или неправильный порядок.
Когда компилятор не может проверить порядок / количество аргументов, это опасно:
test(&my_test /* mandatory, this one has three stages */,
/* stderr else out */ true, /* update counters */ false,
/* skip 1st stage */ true, /* skip 2nd */ false, /* skip 3rd */ true);
Это может удовлетворить ...
test(Test*, bool use_error_stream, bool update_counters, ...);
..., что было бы впечатляющеплохой API.
Обратите внимание, что ссылки обязательно указывают на действительный объект, поэтому некоторым людям нравится использовать их, где это возможно, для сообщения о том, что эта опция является обязательной.Другие люди думают, что важнее намекнуть на то, можно ли изменить параметр на сайте вызова, и написать функции, принимающие неконстантные указатели:
f(my_object); // obviously mandatory, but is it const or not?
f(&my_object); // _might_ be modifiable (if that conventions followed),
// but is it mandatory or not?