我有这种方法在C ++中查找列表中的对象。
Step Config::getStep(string stepName)
{
for(int i=0; i<_NoSteps; i++)
{
if(_Steps[i].getStepNameStr().compare(stepName)==0)
{
return _Steps[i];
}
}
cout << "ERROR. No processing step found for: " << stepName << endl;
// case 1: throw exception
// case 2: return null
}
我在编译时遇到错误:'并非所有控制路径都返回一个值',因为我将其设置为'将警告视为错误'
我想知道如何:
如果找不到对象,如何抛出自定义异常
如何在C#中返回NULL对象:return null
提前致谢。
答案 0 :(得分:3)
像:
cout << "ERROR. No processing step found for: " << stepName << endl;
throw "There was exception, no step was found";
编辑请允许我将@josefx评论添加到我的答案中,这样我就不会被误解。正如他所指出的那样,即使你允许抛出几乎所有东西,这根本不是一个好习惯。你应该尝试只抛出人们期望抛出的对象(比如异常)。在这里,我添加了他如何做到这一点的例子。
throw std::runtime_error("There was an exception, no step was found");
答案 1 :(得分:2)
您可以返回指向对象的指针或引用。在C ++中,与C#不同,您可以按值返回对象,因此,对象将被复制。要通过引用返回它,请写Step& Config::getStep(string stepName)
。
要抛出异常,只需编写throw MissingStepException();
然后像这样处理它:
try {
Step s = c.getStep("step");
}
catch (MissingStepException& ex) {
// handle
}
当然,您需要首先定义MissingStepException
课程。
选择通常做什么:return NULL
或抛出异常取决于你的逻辑:如果缺少步骤是逻辑错误或不太可能的条件,最好使用异常,否则返回NULL
指针会做。
答案 2 :(得分:1)
由于您没有返回指针,因此无法返回NULL
,因此,如果您无法修改函数签名,则需要抛出异常。
你可以这样做:
struct StepNotFoundException : public std::exception
{
std::string stepName;
StepNotFoundException(const std::string& sn) : stepName(sn) {}
};
//....
Step Config::getStep(string stepName)
{
for(int i=0; i<_NoSteps; i++)
{
if(_Steps[i].getStepNameStr().compare(stepName)==0)
{
return _Steps[i];
}
}
cout << "ERROR. No processing step found for: " << stepName << endl;
throw StepNotFoundException(stepName );
}
答案 3 :(得分:1)
如果数据/条件破坏了您的假设,通常代码应该抛出异常。 在这种情况下,如果您希望getStep找不到名称,我认为最好返回一个值然后抛出。
回答你的问题:
1定义,抛出和处理异常
class myException : public std::exception { ... };
try {
...
throw myException();
}
catch (const std::exception &theException) {
...
}
2无法返回NULL。但是,如果它有意义,你可以返回一个空值,但调用代码应该处理这个。
Step Config::getStep(string stepName)
{
...
return Step("");
}