我已经用SDL编程了一段时间,我决定制作一个头文件来简化我的编码。现在我有一个问题;如果我传递一个我不想要的函数参数,我应该
test(NULL);
来自我包含的Windows API或
test(false);
我使用的是C ++,而不是C。
答案 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