哪个更好:NULL还是false?

时间:2011-03-10 00:41:22

标签: c++ windows sdl

我已经用SDL编程了一段时间,我决定制作一个头文件来简化我的编码。现在我有一个问题;如果我传递一个我不想要的函数参数,我应该

test(NULL);

来自我包含的Windows API或

test(false);

我使用的是C ++,而不是C。

4 个答案:

答案 0 :(得分:2)

完全取决于函数参数类型。如果它是一个指针,并且文档说它是有效的,那么你可以传递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 :(得分:1)

Tomalak的回答是调用现有功能的好建议。当您编写一个函数(或者您可以自由更改函数)并且您希望参数是可选的时,您应该尝试设计它以使用法正确,直观且自我记录。如果我们比较:

1) bool really_test = ...;
   test(really_test, my_test);
2) if (...)
       test(my_test);
3) test(... ? &my_test : NULL);

2)使用if - 一个普遍理解的关键字更容易理解,而不是简单地暗示函数的第一个参数可以设置为绕过测试。危险的情况是有人编写代码,例如错误记念或误解API;它很愉快,直到满足NULL条件(可能是prod而不是测试)。

类似地,当某些行为是可选的时,我更喜欢使用枚举来记录这些选项,而不是在调用站点没有通信的布尔值。对比度...

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?

答案 2 :(得分:0)

null是Java(和C#)关键字。它没有出现在C ++代码中的业务。

答案 3 :(得分:0)

nullptr是要走的路。 VC ++ 10已经supports了。 GCC will support它在4.6