【发布时间】:2013-12-14 21:56:41
【问题描述】:
我想知道在 C++ 中终止函数最简单或最方便的方法是什么。
例如我有int function(),我希望它在函数中的某些条件下什么都不做(有点像void),但我不希望整个程序终止。所以,请不要“退出”:D。
我看到人们使用return;,但我不确定它是否安全。
希望你能帮助我。谢谢!
【问题讨论】:
标签: c++ error-handling terminate
我想知道在 C++ 中终止函数最简单或最方便的方法是什么。
例如我有int function(),我希望它在函数中的某些条件下什么都不做(有点像void),但我不希望整个程序终止。所以,请不要“退出”:D。
我看到人们使用return;,但我不确定它是否安全。
希望你能帮助我。谢谢!
【问题讨论】:
标签: c++ error-handling terminate
是的,return 你能回来吗?
或者您可以throw 例外。
在这两种情况下,您都需要注意处理所需的资源释放。
【讨论】:
您需要提供返回值或throw 异常。如果控制流正常返回给调用者,那么只需return 0;。但这表明存在组织问题。
只有返回void的函数才允许没有值的return。
【讨论】:
在声明为 int function() 的函数中,您始终可以返回一些值,例如使用return 0; - 在函数体内的任何时间和任何地方。
你也可以通过抛出一个exception 离开一个函数,这是一个非本地的control flow 转移。
在实践中,您会抛出一些异常,例如
throw std::runtime_error("something bad");
那么call stack 中的某些功能仍然处于活动状态应该catch 那个异常。所以也许你的main 包含
try {
do_the_job(something);
}
catch (std::runtime_error err) {
std::cerr << "bad thing happened:" << err.what() << std::endl;
exit(EXIT_FAILURE);
}
和do_the_job 调用foo 调用bar 调用你的function 哪个throw 在main 中捕获的异常等等......(调用堆栈上的局部值的析构函数被调用)。
【讨论】:
在 C++ 中有 3 种方法可以结束函数:
return一个合适的值throw 异常std::terminate程序这取决于你,程序员,来决定如何处理你所处的情况。一般来说,你会发现自己处于两种情况:
std::terminate 或throw 处理
search可能失败),一般通过调用throw或返回一个标记值来处理。因此,由于在您的情况下,我们似乎在谈论一种功能情况,您可能会问自己,这种情况是否是调用者方面的错误(在这种情况下,异常是一个好的候选人)或者如果这是正常情况(例如search没有找到任何东西),在这种情况下,哨兵值可能是最好的。
对于哨兵值,我见过一些方法:
nullptr 作为 Sentinel),如果需要,可以是一个智能指针boost::optional<Type>(并使用 boost::none 作为 Sentinel)确实有很多方案可供选择;如果你返回一个副本,我会推荐后者,如果你返回一个预先存在的对象的句柄,我会推荐后者。
【讨论】:
terminate 适用于违反析构函数的先决条件的情况。
如果你的函数有返回类型int,那么如果你返回,你需要返回一个值,而不仅仅是return;。
你的函数的返回值可能对调用者有一些意义。因此适用以下三种情况之一:
1) 有一些可用的整数值并不意味着“我做了某事”。因此,您可以记录该值意味着“我什么都没做”,然后返回。 0 和 -1 通常是最有可能用于此目的的值,但这完全取决于函数的作用和返回值的含义。
2) 没有可用的值不代表“我做了某事”,因此该函数无法返回一个值来表示“我什么也没做”。然后,您可以更改函数的签名,为其提供一种指示它是否执行任何操作的方法——例如,返回一个 pair<bool,int> 而不仅仅是一个 int,其中一个值表示成功/失败,另一个值表示有意义关于成功而不是失败。或者,您可以将int & 参数添加到function,您将在其中存储当前用作返回值的值,并将返回类型更改为bool,它仅指示成功或失败。或者,如果所讨论的情况是函数无法执行其设计的操作,那么您可以抛出异常(并记录函数可能抛出的内容)。
在上述两种情况下,调用该函数的现有代码可能必须更新(如果您更改签名肯定会更新)。这就导致了第三种情况:
3) 函数没有办法表明它什么也没做,并且你不能改变函数的接口(例如,也许它已经记录了不抛出而你不想改变现有调用者依赖的事实)。那我恐怕你处于你不想要的境地。如果一个函数发现即使通过抛出它也无法履行其合同义务,那么你所能做的就是terminate或exit。程序无法继续,因为调用者完全有权期望该函数会做“某事”,但您不能这样做。这通常表明设计存在某种错误,或者您正在实现的接口不够灵活,无法支持您的计划。
【讨论】:
简单地使用return 可能会给您带来一些麻烦,因为编译器要求您实际返回一个值,并且任何合理的人在阅读您的原型时都会期望如此。对于您的情况,最好的方法是 throw 例外。
编辑:下面提醒我,是的,只有在出现不可恢复的错误时才应抛出异常。也许一个简单的return 是最快的方法。但是,您应该采取的正确行为是在满足您的条件时引发某种错误标志。
【讨论】: