Returning a “NULL reference” in C++?

2020-01-30 06:04发布

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

function getSomething(name) {
    if (content_[name]) return content_[name];
    return null; // doesn't exist
}

I return an object if it exists or null if not.

What would be the equivalent in C++ using references? Is there any recommended pattern in general? I saw some frameworks having an isNull() method for this purpose:

SomeResource SomeClass::getSomething(std::string name) {
    if (content_.find(name) != content_.end()) return content_[name];
    SomeResource output; // Create a "null" resource
    return output;
}

Then the caller would check the resource that way:

SomeResource r = obj.getSomething("something");
if (!r.isNull()) {
    // OK
} else {
    // NOT OK
}

However, having to implement this kind of magic method for each class seems heavy. Also it doesn't seem obvious when the internal state of the object should be set from "null" to "not null".

Is there any alternative to this pattern? I already know it can be done using pointers, but I am wondering how/if it can be done with references. Or should I give up on returning "null" objects in C++ and use some C++-specific pattern? Any suggestion on the proper way to do that would be appreciated.

8条回答
可以哭但决不认输i
2楼-- · 2020-01-30 06:52

I can think of a few ways to handle this:

  • As others suggested, use boost::optional
  • Make the object have a state that indicates it is not valid (Yuk!)
  • Use pointer instead of reference
  • Have a special instance of the class that is the null object
  • Throw an exception to indicate failure (not always applicable)
查看更多
兄弟一词,经得起流年.
3楼-- · 2020-01-30 07:00

unlike Java and C# in C++ reference object can't be null.
so I would advice 2 methods I use in this case.

1 - instead of reference use a type which have a null such as std::shared_ptr

2 - get the reference as a out-parameter and return Boolean for success.

bool SomeClass::getSomething(std::string name, SomeResource& outParam) {
    if (content_.find(name) != content_.end()) 
    {
        outParam = content_[name];
        return true;
    }
    return false;
}
查看更多
登录 后发表回答