Что лучше: NULL или false? - PullRequest
       12

Что лучше: NULL или false?

0 голосов
/ 10 марта 2011

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

test(NULL);

из Windows API, который я включаю, или

test(false);

Я использую C ++, а не C.

Ответы [ 4 ]

2 голосов
/ 10 марта 2011

Это полностью зависит от типа параметра функции. Если это указатель, а в документации сказано, что он действителен, тогда вы можете передать C ++ NULL (что на самом деле просто 0).

Примеры:

// Bad; strlen expects a pointer to a real, existing C-string buffer
std::cout << strlen(NULL);

/**
 * Function that does something.
 * 
 * @param ptr Pointer to buffer, or NULL to do nothing
 */
void myFunc(const char* ptr);

// OK; the function is designed to be ok with it
myFunc(NULL);

Так что не все функции примут это как действительное для указателя.

Конечно, он не будет действителен для любого другого типа (хотя вам и не удастся передать его за int, это не совсем то, что вы ожидаете сделать). NULL не является универсальным "Я хочу отказаться от этого параметра функции". Вы просто не можете сделать это в общем случае.

Вывод: Зависит от того, что test.

И я понятия не имею, что должно быть null.

1 голос
/ 10 марта 2011

Ответ Томалака - отличный совет для вызова существующих функций.Когда вы пишете функцию (или когда вы можете изменять ее) и хотите, чтобы параметры были необязательными, вы должны попытаться спроектировать ее так, чтобы использование было правильным, интуитивно понятным и самодокументируемым.Если мы сравним:

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?
0 голосов
/ 10 марта 2011

nullptr это путь.VC ++ 10 уже поддерживает это.GCC будет поддерживать в 4.6

0 голосов
/ 10 марта 2011

null - ключевое слово Java (и C #). Это не имеет никакого дела, появляющегося в коде C ++.

...