我应该抛出一个异常吗 我是C程序员,但现在我想得到更多的C++。br/> 我知道C++的基础知识,但我不知道如何处理错误。br/>

我应该抛出一个异常吗 我是C程序员,但现在我想得到更多的C++。br/> 我知道C++的基础知识,但我不知道如何处理错误。br/>,c++,exception,error-handling,C++,Exception,Error Handling,例如:我正在写一本图书馆。我创建了一个构造函数,它请求一个整数作为参数 如果该整数大于50,则为错误。 在C++中,我会抛出 ArgumentOutOfRange < /Cord>异常,但是在C++中,我应该做什么?< P> > C中的一样:抛出异常。这是防止构造对象的唯一方法 对于抛出什么是一个很好的标准选择。这取决于大于50的整数是否可能作为正常程序流的一部分传递给构造函数,或者这是否是一个例外情况。但一般来说,让对象构造失败的唯一方法是抛出异常 您的用户代码可能如下所示: int n =

例如:我正在写一本图书馆。我创建了一个构造函数,它请求一个整数作为参数
如果该整数大于50,则为错误。 在C++中,我会抛出<代码> ArgumentOutOfRange < /Cord>异常,但是在C++中,我应该做什么?

< P> > C中的一样:抛出异常。这是防止构造对象的唯一方法


对于抛出什么是一个很好的标准选择。

这取决于大于50的整数是否可能作为正常程序流的一部分传递给构造函数,或者这是否是一个例外情况。但一般来说,让对象构造失败的唯一方法是抛出异常

您的用户代码可能如下所示:

int n = parse_user_input()

if (n < 50)
{
    Foo x(n);
    x.do_cool_stuff();
}
else
{
    // report user error
}
int n=parse\u user\u input()
如果(n<50)
{
foox(n);
x、 你喜欢酷的东西吗;
}
其他的
{
//报告用户错误
}
也就是说,您实际上不会对正常的控制流使用异常。使用这种代码模式,如果参数超出范围,则
Foo::Foo(int)
抛出异常是非常好的

您可以在中找到有用的标准异常类

< >我将抛出范围异常,但在C++中应该怎么做?

首先,你应该考虑这是否是你的函数的先决条件,而不负责检查值是否在调用方的范围内。p> 如果您决定使用此选项,那么使用超出范围的值调用函数将是未定义的行为,并且在函数内部您可以使用调试断言来帮助您发现可能的误用,而无需引发任何异常

另一方面,如果您决定函数应该具有广泛的约定,并且在参数超出允许范围时通过抛出异常以定义良好的方式进行反应,那么您可以抛出异常

例如:我正在写一本图书馆[…]

如果你正在编写一个库,这意味着你不知道你的客户在性能和健壮性方面的确切要求,你可以考虑提供两个这样的函数:一个有一个宽的合同来抛出异常,一个是一个假设客户提供有意义的输入的窄合同。p> 这样,库的用户可以根据他们的用例决定是否可以在每次调用函数时支付检查输入正确性的开销

这是C++标准库对 STD::vector < /Cuff>所采用的策略,它提供了一个非限制的基于索引访问集合元素的窄合同(如果索引超出界限,该函数具有未定义的行为)以及一个成员函数,它执行索引检查,如果索引超出界限,抛出异常。

< P>从C++ FAQ:

摘录:

抛出异常

构造函数没有返回类型,因此无法使用 返回代码。因此,发出构造函数失败信号的最佳方法是 抛出异常。如果你没有选择使用 例外情况下,“最不坏”的解决方法是将对象放入 “僵尸”状态,通过设置内部状态位使对象动作 有点像它死了,尽管从技术上说它还活着


因此,抛出
std::invalid_参数
std::out_of_range
对于您的情况来说是完全可以接受的。如果对您的情况有利,您还可以抛出一个自定义异常。在C++ FAQ中,参见:

>斯特凡的复制,在C++中,不使用异常来控制程序流。远离问题——创建一个工厂可能是一个好主意,它可以完成所有必需的检查,并避免使用错误原因的异常+1断言(前置/后置条件)、std::vector示例和选项。@Freddy:很高兴你发现它很有用。你关于异常的冗长而准确的回答可能会导致OP走到错误的一边。Kerrek SB的下一个答案也应该在这种情况下考虑,以避免评论,比如从@stefan到最初的问题什么是窄契约还是宽契约?@AndyProwl By()我假设具有宽契约的函数永远不会有未定义的行为(因此,它永远不会抛出?)而根据呼叫条件的不同,窄的可能是未定义的。但你写过:“一个有着广泛合同的人会抛出例外”。。。你能解释一下吗?谢谢