C++ 如果未找到搜索结果,则返回“NULL”对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2639255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Return a "NULL" object if search result not found
提问by aduric
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) { ... }
我对 C++ 很陌生,所以我在学习时倾向于使用很多 Java 主义进行设计。无论如何,在 Java 中,如果我有一个带有“搜索”方法的类,该方法T
将从Collection< T >
与特定参数匹配的对象返回一个对象,我将返回该对象,如果在集合中找不到该对象,我将返回null
. 然后在我的调用函数中,我会检查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.
在 C++ 中,我发现null
如果对象不存在,我将无法返回值。我只想返回一个 T 类型的“指示器”,它通知调用函数没有找到对象。我不想抛出异常,因为这并不是真正的特殊情况。
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?
我该如何更改它以便我可以提供那种标记?
采纳答案by Jesse Beder
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:
在 C++ 中,引用不能为空。如果您想在未找到任何内容的情况下选择性地返回 null,则需要返回一个指针,而不是一个引用:
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.)
(顺便说一句,我有点担心你的方法会const
返回一个非const
属性。出于哲学原因,我建议返回const Attr *
。如果你也想修改这个属性,你可以用一个非const
方法重载也返回一个非const
属性。)
回答by Kaz Dragon
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; }
通过引用返回,并且通过异常信号无法找到。
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; }
指针返回
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.
很容易忘记检查 getAttribute 的结果是否为非 NULL 指针,并且很容易导致错误。
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&>(); }
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.
boost::optional 表示这里到底发生了什么,并且有简单的方法来检查是否找到了这样的属性。
Side note: std::optional was recently voted into C++17, so this will be a "standard" thing in the near future.
旁注:std::optional 最近被选入 C++17,所以这将在不久的将来成为“标准”的东西。
回答by Mark Ransom
You can easily create a static object that represents a NULL return.
您可以轻松创建一个表示 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;
};
And somewhere in a source file:
在源文件中的某处:
static Attr AttrNull;
回答by Brian R. Bondy
If you want a NULL
return value you need to use pointers instead of references.
如果你想要一个NULL
返回值,你需要使用指针而不是引用。
References can't themselves be NULL
.
引用本身不能是NULL
.
(Note to the future comment posters: Yes you can have the address of a reference be NULL if you really really try to).
(注意未来的评论海报:是的,如果您真的尝试,您可以将引用的地址设为 NULL)。
See my answer here for a list of differences between references and pointers.
回答by A.B.
As you have figured out that you cannot do it the way you have done in Java (or C#). Here is another suggestion, you could pass in the reference of the object as an argument and return bool value. If the result is found in your collection, you could assign it to the reference being passed and return ‘true', otherwise return ‘false'. Please consider this code.
正如您发现的那样,您不能像在 Java(或 C#)中那样做。这是另一个建议,您可以将对象的引用作为参数传入并返回 bool 值。如果在您的集合中找到结果,您可以将其分配给正在传递的引用并返回“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;
}
The function above has to find the Operator against the key 'token', if it finds the one it returns true and assign the value to parameter Operator& op.
上面的函数必须根据键“token”找到 Operator,如果找到,则返回 true 并将值分配给参数 Operator& op。
The caller code for this routine looks like this
此例程的调用方代码如下所示
Operator opr;
if (OperatorList::tryGetOperator(strOperator, opr))
{
//Do something here if true is returned.
}
回答by JSB????
The reason that you can't return NULL here is because you've declared your return type as Attr&
. The trailing &
makes the return value a "reference", which is basically a guaranteed-not-to-be-null pointer to an existing object. If you want to be able to return null, change Attr&
to Attr*
.
此处不能返回 NULL 的原因是因为您已将返回类型声明为Attr&
. 尾随&
使返回值成为“引用”,它基本上是一个指向现有对象的保证非空指针。如果您希望能够返回 null,请更改Attr&
为Attr*
.
回答by codaddict
You are unable to return NULL
because the return type of the function is an object reference
and not a pointer
.
您无法返回,NULL
因为函数的返回类型是对象reference
而不是pointer
。
回答by Created
You can try this:
你可以试试这个:
return &Type();