So I’m having a rather tumultuous conversion to C++ from Java/C#. Even though I feel like I understand most of the basics, there are some big fat gaping holes in my understanding.
For instance, consider the following function:
Fruit&
FruitBasket::getFruitByName(std::string fruitName)
{
std::map<std::string,Fruit>::iterator it = _fruitInTheBascit.find(fruitName);
if(it != _fruitInTheBascit.end())
{
return (*it).second;
}
else
{
//I would so love to just return null here
}
}
Where _fruitsInTheBascit is a std::map<std::string,Fruit>. If I query getFruitByName("kumquat") you know it’s not going to be there – who eats kumquats? But I don’t want my program to crash. What should be done in these cases?
P.S. tell me of any other stupidity that I haven’t already identified.
There is no such thing in C++ as a null reference, so if the function returns a reference, you can’t return null. You have several options:
Change the return type so that the function returns a pointer; return null if the element is not found.
Keep the reference return type but have some sort of “sentinel” fruit object and a return a reference to it if the object is not found.
Keep the reference return type and throw an exception (e.g.,
FruitNotFoundException) if the fruit is not found in the map.I tend to use (1) if a failure is likely and (3) if a failure is unlikely, where “likely” is a completely subjective measure. I think (2) is a bit of a hack, but I’ve seen it used neatly in some circumstances.
As an example of an “unlikely” failure: in my current project, I have a class that manages objects and has a function
is_object_presentthat returns whether an object is present and a functionget_objectthat returns the object. I always expect that a caller will have verified the existence of an object by callingis_object_presentbefore callingget_object, so a failure in this case is quite unlikely.