C++中的安全指针解除引用

Mik*_*ail 14 c++ exception nullpointerexception dereference

在我们的代码库中,我们有许多这样的结构:

auto* pObj = getObjectThatMayVeryRarelyBeNull();
if (!pObj) throw std::runtime_error("Ooops!");
// Use pObj->(...)
Run Code Online (Sandbox Code Playgroud)

在99.99%的情况下,不会触发此检查.我正在考虑以下解决方案:

auto& obj = deref_or_throw(getObjectThatMayVeryRarelyBeNull());
// Use obj.(...)
Run Code Online (Sandbox Code Playgroud)

deref_or_throw声明如下:

template<class T> T& deref_or_throw(T* p) {
  if (p == nullptr) { throw std::invalid_argument("Argument is null!"); }
  return *p;
}
Run Code Online (Sandbox Code Playgroud)

该代码更清晰,可以根据需要使用.

问题是:我是否重新发明轮子?在标准或提升中是否有一些相关的解决方案?或者你对解决方案有一些评论?

PS.相关问题(没有令人满意的答案):是否存在与NullPointerException相当的C++

ste*_*fan 4

有两种方法可以处理“空指针的罕见情况”问题。首先,这是建议的异常解决方案。对于这一点,该方法deref_or_throw是一件好事,尽管我更愿意抛出runtime_error, 而不是invalid_argument异常。您也可以考虑命名它NullPointerException如果您愿意,

但是,如果该ptr != nullptr情况实际上是该算法的先决条件,那么您应该尽力在拥有该非空情况时实现 100% 的安全性。一个assert是合适的。

优点assert

  • 发布模式下运行时无成本
  • 向开发人员明确表示,他有责任避免这种情况发生。

缺点assert

  • 发布模式下潜在的未定义行为

您还应该考虑编写一个方法getObjectThatMayNeverBeNullButDoingTheSameAsGetObjectThatMayVeryRarelyBeNull():保证返回一个指向对象的非空指针的方法,该对象在其他方面与原始方法完全等效。但是,如果您可以加倍努力,我强烈建议无论如何不要返回原始指针。拥抱 C++11 并按值返回对象:-)