如果我有一个函数接受一个永远不应该为NULL的指针,我通常会这样做:
void Foo(const somePointer* ptr)
{
if (ptr == NULL)
{
// Throw assertion
return;
}
// Do something
}
所以现在我每次检查指针是否为NULL,如果它首先没有设置为NULL而且没有分配,那么该检查是无用的。所以现在我在想是否应该像这样定义我的函数(尽管我意识到这并不能保证我得到一个有效的对象,至少它不会是NULL):
void Foo(const somePointer& ptr)
{
// No need to check anymore, client is responsible
// Do something
}
在我做之前(或不做,取决于我得到的答案),我想我会问这里,看看每个人都要说什么,尤其是它的优点和缺点。
答案 0 :(得分:5)
好吧,如果您从未希望传入不存在的对象,请使用引用(注意:不存在,而不是无效)。
如果您想要这种可能性,请使用指针。
答案 1 :(得分:4)
很大程度上取决于代码的形状 - 如果你写了很多这样的东西:
A * a = new A();
f( a );
然后f()获取指针似乎是明智的,而不是必须写:
f( *a );
就个人而言,我几乎从未检查过NULL,新的不能返回一个,如果你发现你有一个你可能已经在UB土地。
答案 2 :(得分:4)
我认为安全检查毫无意义。不过,作为文档,这是非常值得的。
如果进行更改,所有会发生的事情是某些用户将更改此代码:
somePointer *ptr = something();
Foo(ptr);
对此:
somePointer *ptr = something();
Foo(*ptr);
现在,如果ptr
为null,则第一个代码无效,将null传递给参数“永远不应该为NULL”的函数是错误的。第二个代码也是无效的,取消引用空指针是他们的错。
它作为文档很有用,因为当他们输入他们会想到的*
字符时,“哦,坚持下去,最好不要为空”。然而,如果您所做的只是文档,null是无效输入(比如说,strlen
确实如此),那么他们必须阅读文档才能知道不传入空指针。从理论上讲,代码的用户将检查文档而不是仅仅用他的脸将键盘捣碎,直到他有一些编译的东西,并假设它会起作用。在实践中,我们都有不那么聪明的时刻。