这似乎很多工作;每次使用对象时检查null。
我被告知,检查空指针是个好主意,这样您就不必花时间寻找出现分段错误的位置。
想知道这里的社区是怎么想的?
答案 0 :(得分:18)
尽可能使用引用,因为不能为空,因此您不必检查它们是否为空。
在函数参数和其他地方检查null是一个好习惯,你可能正在处理其他人传递给你的指针。但是,在你自己的代码中,你可能有指针,你知道它总是指向一个有效的对象,所以null检查可能有点过分......只是使用你的常识。
我不知道它是否真的有助于调试,因为任何调试器都会非常清楚地显示使用了空指针,并且不需要很长时间才能找到它。它更多的是确保在另一个程序员传入NULL时不会崩溃,或者在调试版本中由断言拾取错误。
答案 1 :(得分:12)
没有。您应该首先确保指针未设置为NULL。请注意,在标准C ++中:
int * p = new int;
然后p永远不能为NULL,因为如果分配失败,new将抛出异常。
如果你正在编写可以将指针作为参数的函数,你应该像这样对待它们
// does something with p
// note that p cannot be NULL
void f( int * p );
换句话说,您应记录该功能的要求。您还可以使用assert()来检查是否有人忽略了您的文档(如果有的话,这是他们的问题,而不是您的问题),但我必须承认,随着时间的推移我已经离开了 - 只需说出函数需要的内容,并将责任留给来电者。
第三点建议就是不使用指针 - 我见过的大多数C ++代码都过度指向了一个荒谬的指针 - 你应该尽可能使用值和引用。
答案 2 :(得分:4)
一般来说,我建议不要这样做,因为它会让你的代码更难阅读,如果指针实际上是NULL,你还必须提出一些明智的处理方法。
在我的C ++项目中,我只检查指针(如果我使用指针)是否为NULL,只有它可能是指针的有效状态。如果指针永远不会实际为NULL,则检查NULL是有点无意义的,因为您正在尝试解决一些您应该修复的编程错误。
此外,当您觉得需要检查指针是否为NULL时,您可能应该更清楚地定义谁拥有指针/对象。
此外,您永远不必检查new
是否返回NULL,因为它永远不会返回NULL。如果它无法创建对象,它将抛出异常。
答案 3 :(得分:2)
我讨厌检查nulls添加的代码量,所以我只对我导出给另一个人的函数执行此操作。
如果在内部使用该函数,并且我知道如何使用它,我不会检查空值,因为它会使代码太乱。
答案 4 :(得分:1)
答案是肯定的,如果你不能控制对象。也就是说,如果对象是从您无法控制的某个方法返回的,或者在您自己的代码中,您希望(或者可能)对象可以为null。
它还取决于代码的运行位置。如果您正在编写客户/用户将看到的专业代码,那么他们通常会看到空指针问题。如果您可以事先检测到它并打印出一些调试信息或以“更好”的方式向它们报告,那就更好了。
如果只是非正式使用的代码,您可能无需任何其他信息就能理解空指针的来源。
答案 5 :(得分:1)
我想我可以对NULL指针进行大量检查,只需要一个段错误(调试)。
性能损失可以忽略不计。两个说明。如果测试成功,则测试寄存器==零,分支。根据机器的不同,如果寄存器加载设置条件代码(有些条件代码),则可能只有一条指令。
答案 6 :(得分:1)
其他人(AshleysBrain和Neil Butterworth)已经正确回答,但我会在这里总结一下:
但是,有一个角落案例,引用可能无效/ NULL:
void foo(T & t)
{
t.blah() ;
}
void bar()
{
T * t = NULL ;
foo(*t) ;
}
编译器可能会编译它,然后,在执行时,代码将在t.blah()
行崩溃(如果T :: blah()以某种方式使用this
。
但是,这是作弊/破坏:bar()
函数解除引用t
而未验证t
的作者不为空。因此,即使崩溃发生在foo()
中,错误也会出现在bar()
的代码中,bar()
的作者负责。
所以,是的,尽可能多地使用引用,知道这个角落的情况,并且不用费心去防止被破坏的引用......
如果你真的需要在C ++中使用指针,除非你100%确定指针不是NULL(某些函数保证那种东西),然后总是测试指针。
答案 7 :(得分:0)
我认为这对于调试版本来说是一个好主意 在发行版中,检查空指针可能会导致性能下降 此外,在某些情况下,您可以检查父函数中的指针值,并避免检查其子函数。
答案 8 :(得分:0)
如果指针作为参数传递给函数,则确保它们在函数开头有效。否则,没有多大意义。 new
在失败时抛出异常。