函数参数作为引用,以避免检查NULL

Function argument as reference to avoid checking for NULL

本文关键字:检查 NULL 参数 引用 函数      更新时间:2023-10-16

如果我有一个函数接收一个永远不应该为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
}

在我这样做之前(或者不这样做,取决于我在这里得到的答案),我想我会在这里问,看看每个人都会说什么,尤其是利弊。

如果您从不希望传入不存在的对象,请使用引用(注意:不存在,无效)
如果你想要这种可能性,就用一个指针。

很大程度上取决于代码的形状——如果你写了很多这样的东西:

A * a = new A();
f( a );

那么f()取一个指针似乎是明智的,而不是必须写:

f( *a );

就我个人而言,我几乎从不检查NULL,新的不能退货,如果你发现你有一个,你可能已经在UB了。

我认为这作为一项安全检查毫无意义。不过,作为文档,它的价值微乎其微。

如果你做了改变,所有的事情都会发生,一些用户会改变这个代码:

somePointer *ptr = something();
Foo(ptr);

对此:

somePointer *ptr = something();
Foo(*ptr);

现在,如果ptr为null,那么第一个代码是无效的,这是他们将null传递给参数"永远不应该为null"的函数的错误。第二个代码也是无效的,这是他们取消引用空指针的错误。

它作为文档很有用,因为当他们键入*字符时,他们可能会想,"哦,等一下,这个最好不要为空"。然而,如果您所做的只是文档中的null是无效输入(比如strlen),那么他们必须阅读文档才能知道不要传入null指针。理论上,代码的用户会检查文档,而不是只是用脸捣碎键盘,直到他有了可以编译的东西,并假设这会起作用。在实践中,我们都有不那么聪明的时刻。