In our code base we have many constructions like this:
auto* pObj = getObjectThatMayVeryRarelyBeNull();
if (!pObj) throw std::runtime_error("Ooops!");
// Use pObj->(...)
In 99.99% of cases this check is not triggered. I'm thinking about the following solution:
auto& obj = deref_or_throw(getObjectThatMayVeryRarelyBeNull());
// Use obj.(...)
Where deref_or_throw
is declared as follows:
template<class T> T& deref_or_throw(T* p) {
if (p == nullptr) { throw std::invalid_argument("Argument is null!"); }
return *p;
}
That code is much clearer and works as I need.
The question is: am I reinventing the wheel? Is there some related solution in standard or boost? Or do you have some comments on the solution?
PS. Related question (with no satisfying answer): Is there a C++ equivalent of a NullPointerException
There are two ways of dealing with the "rare case of null-pointer" issue. First, it's the proposed exception solution. For this, the method deref_or_throw
is a good thing, though I would prefer to throw a runtime_error
, rather than an invalid_argument
exception. You may also consider naming it NullPointerException
, if you prefer that.
However, if the ptr != nullptr
case is actually a precondition to the algorithm, you should try your best to achieve 100% safety in having this non-null case. An assert
is the appropriate thing in this case.
Advantages of assert
:
Disadvantages of assert
:
You should also consider writing a method getObjectThatMayNeverBeNullButDoingTheSameAsGetObjectThatMayVeryRarelyBeNull()
: A method that is guaranteed to return a non-null pointer to an object that is otherwise completely equivalent to your original method. However, if you can go the extra mile, I would strongly suggest to not returning a raw pointer anyway. Embrace C++11 and return objects by value :-)