Returning a “NULL reference” in C++?

前端 未结 8 593
旧巷少年郎
旧巷少年郎 2020-12-05 00:02

In dynamically typed languages like JavaScript or PHP, I often do functions such as:

function getSomething(name) {
    if (content_[name]) return content_[na         


        
8条回答
  •  余生分开走
    2020-12-05 00:17

    You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.

    1. With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):

      SomeResource* SomeClass::getSomething(std::string name) {
          std::map::iterator it = content_.find(name);
          if (it != content_.end()) 
              return &(*it);  
          return NULL;  
      }
      
    2. Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):

      std::pair SomeClass::getSomething(std::string name) {
          std::map::iterator it = content_.find(name);
          if (it != content_.end()) 
              return std::make_pair(*it, true);  
          return std::make_pair(SomeResource(), false);  
      }
      
    3. Using boost::optional:

      boost::optional SomeClass::getSomething(std::string name) {
          std::map::iterator it = content_.find(name);
          if (it != content_.end()) 
              return *it;  
          return boost::optional();  
      }
      

    If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.

    I also modified your example so you're not searching the map twice (by reusing the iterator).

提交回复
热议问题