如果找不到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();