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

3
如果我有一个函数需要传入指针,但是该指针不应为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
}

在我做出决定之前(或者不做,这取决于我在这里得到的答案),我想在这里询问并看看大家的意见,特别是它的优缺点。

3个回答

5

如果你绝对不想让一个不存在的对象被传递进来,就使用引用(注意:不存在,而不是无效)。
如果你希望有这种可能性,就使用指针。


4
很多事情都取决于你的代码结构——如果你写了很多这样的内容:
A * a = new A();
f( a );

那么,让f()接受一个指针似乎是合理的选择,而不是必须写成:

f( *a );

个人而言,我几乎从不检查NULL值,因为new操作符无法返回NULL值,如果你发现有NULL值存在,那么你可能已经处于未定义行为的领域。


4
我认为这个作为安全检查是毫无意义的。不过,它可以作为文档略有价值。
如果你进行更改,那么只会导致某些用户更改以下代码:
somePointer *ptr = something();
Foo(ptr);

转化为:

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

现在,如果 ptr 是 null,那么第一个代码是无效的,他们将 null 传递给“不应该为 NULL”的参数的函数,这是他们的错误。第二个代码也是无效的,他们对 null 指针进行了引用操作,这也是他们的错误。
这在文档中非常有用,因为当他们键入 * 字符时,他们会想到,“哦,等等,这不应该是 null”。而如果您所做的只是记录 null 是无效输入(例如,strlen),则他们必须阅读文档才能知道不要传递空指针。理论上,您的代码的用户将检查文档,而不是只是随意敲键盘,直到编译出可用程序的方法,并假设它可以工作。实际上,我们都会有不太聪明的时刻。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接