Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return a "NULL" object if search result not found

I'm pretty new to C++ so I tend to design with a lot of Java-isms while I'm learning. Anyway, in Java, if I had class with a 'search' method that would return an object T from a Collection< T > that matched a specific parameter, I would return that object and if the object was not found in the collection, I would return null. Then in my calling function I would just check if(tResult != null) { ... }

In C++, I'm finding out that I can't return a null value if the object doesn't exist. I just want to return an 'indicator' of type T that notifies the calling function that no object has been found. I don't want to throw an exception because it's not really an exceptional circumstance.

This is what my code looks like right now:

class Node {     Attr& getAttribute(const string& attribute_name) const {        //search collection        //if found at i             return attributes[i];        //if not found             return NULL; // what should this be?     }  private:     vector<Attr> attributes; } 

How can I change it so I can give that kind of marker?

like image 420
aduric Avatar asked Apr 14 '10 16:04

aduric


People also ask

Which method returns null if the object Cannot be found?

In C++, I can think of 3 different flavors of setting up a method that finds an object. Object *findObject(Key &key); Return null when an object can't be found. Nice and simple.

How do you return a null object?

In Java, a null value can be assigned to an object reference of any type to indicate that it points to nothing. The compiler assigns null to any uninitialized static and instance members of reference type. In the absence of a constructor, the getArticles() and getName() methods will return a null reference.

Can I return null in C++?

Yes, it is totally fine to return NULL.

What happens when return null?

Returning null Creates More Work An ideal function, like an assistant cook, will encapsulate work and produce something useful. A function that returns a null reference achieves neither goal. Returning null is like throwing a time bomb into the software. Other code must a guard against null with if and else statements.


2 Answers

In C++, references can't be null. If you want to optionally return null if nothing is found, you need to return a pointer, not a reference:

Attr *getAttribute(const string& attribute_name) const {    //search collection    //if found at i         return &attributes[i];    //if not found         return nullptr; } 

Otherwise, if you insist on returning by reference, then you should throw an exception if the attribute isn't found.

(By the way, I'm a little worried about your method being const and returning a non-const attribute. For philosophical reasons, I'd suggest returning const Attr *. If you also may want to modify this attribute, you can overload with a non-const method returning a non-const attribute as well.)

like image 131
Jesse Beder Avatar answered Sep 29 '22 03:09

Jesse Beder


There are several possible answers here. You want to return something that might exist. Here are some options, ranging from my least preferred to most preferred:

  • Return by reference, and signal can-not-find by exception.

    Attr& getAttribute(const string& attribute_name) const  {    //search collection    //if found at i         return attributes[i];    //if not found         throw no_such_attribute_error; }

It's likely that not finding attributes is a normal part of execution, and hence not very exceptional. The handling for this would be noisy. A null value cannot be returned because it's undefined behaviour to have null references.

  • Return by pointer

    Attr* getAttribute(const string& attribute_name) const  {    //search collection    //if found at i         return &attributes[i];    //if not found         return nullptr; }

It's easy to forget to check whether a result from getAttribute would be a non-NULL pointer, and is an easy source of bugs.

  • Use Boost.Optional

    boost::optional<Attr&> getAttribute(const string& attribute_name) const  {    //search collection    //if found at i         return attributes[i];    //if not found         return boost::optional<Attr&>(); }

A boost::optional signifies exactly what is going on here, and has easy methods for inspecting whether such an attribute was found.


Side note: std::optional was recently voted into C++17, so this will be a "standard" thing in the near future.

like image 43
Kaz Dragon Avatar answered Sep 29 '22 02:09

Kaz Dragon