如果找不到search结果,则返回“NULL”对象

我对C ++相当陌生,所以在学习的时候我倾向于devise大量的Java-isms。 无论如何,在Java中,如果我有一个“search”方法的类,将返回一个Collection< T >匹配一个特定参数的对象T ,我会返回该对象,如果对象没有在集合中find,我会返回null 。 然后在我的调用函数,我只是检查if(tResult != null) { ... }

在C ++中,我发现如果对象不存在,我不能返回null值。 我只想返回一个types为T的“指示符”,通知调用函数没有find对象。 我不想抛出exception,因为这不是一个真正的例外情况。

这就是我现在的代码:

 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; } 

我怎样才能改变它,所以我可以给这种标记?

在C ++中,引用不能为空。 如果你想有select地返回null,如果没有find,你需要返回一个指针,而不是一个引用:

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

否则,如果你坚持通过引用返回,那么你应该抛出一个exception,如果没有find属性。

(顺便说一句,我有点担心你的方法是const并返回一个非常量属性。出于哲学原因,我build议返回const Attr * 。如果你也可能想要修改这个属性,你可以重载一个非const方法也返回一个非const属性。)

这里有几个可能的答案。 你想要返回可能存在的东西。 这里有一些select,从我的最不喜欢到最受欢迎:

  • 通过引用返回,并且信号不能被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; } 

没有find属性可能是执行的正常部分,因此不是非常特殊的。 处理这将是嘈杂。 空值不能被返回,因为它的未定义行为具有空引用。

  • 通过指针返回

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

忘记检查getAttribute的结果是否为非空指针很容易,并且是错误的一个简单来源。

  • 使用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&>(); } 

一个boost :: optional表示这里到底发生了什么,并且有检查这个属性是否被find的简单方法。


附注:std :: optional最近被投票到C ++ 17,所以这将是一个“标准”的东西在不久的将来。

您可以轻松创build一个表示NULL返回值的静态对象。

 class Attr; extern Attr AttrNull; class Node { .... Attr& getAttribute(const string& attribute_name) const { //search collection //if found at i return attributes[i]; //if not found return AttrNull; } bool IsNull(const Attr& test) const { return &test == &AttrNull; } private: vector<Attr> attributes; }; 

并在源文件中的某个地方:

 static Attr AttrNull; 

如果你想要一个NULL返回值,你需要使用指针而不是引用。

引用本身不能为NULL

(请注意将来的评论海报:是的,如果你真的想尝试的话,你可以得到一个引用的地址为NULL)。

查看我的答案在这里查看引用和指针之间的区别列表 。

正如你已经知道,你不能像你在Java(或C#)中所做的那样做。 这里有另外一个build议,你可以将对象的引用作为参数传入并返回bool值。 如果在您的collections中find结果,您可以将其分配给正在传递的引用,并返回“true”,否则返回“false”。 请考虑这个代码。

 typedef std::map<string, Operator> OPERATORS_MAP; bool OperatorList::tryGetOperator(string token, Operator& op) { bool val = false; OPERATORS_MAP::iterator it = m_operators.find(token); if (it != m_operators.end()) { op = it->second; val = true; } return val; } 

上面的函数必须find操作符的关键“标记”,如果它find一个它返回true,并将值赋给参数Operator&op。

这个例程的调用者代码如下所示

 Operator opr; if (OperatorList::tryGetOperator(strOperator, opr)) { //Do something here if true is returned. } 

这里不能返回NULL的原因是因为你声明了你的返回types为Attr& 。 尾部&使得返回值成为一个“引用”,它基本上是一个保证不是空指针到一个现有的对象。 如果您希望能够返回null,请将Attr&更改为Attr*

您不能返回NULL因为函数的返回types是对象reference而不是pointer

你可以试试这个:

 return &Type(); 
Interesting Posts