Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用try-Catch异常处理程序和if-else条件检查之间的区别?_C++_If Statement_Exception Handling - Fatal编程技术网

C++ 使用try-Catch异常处理程序和if-else条件检查之间的区别?

C++ 使用try-Catch异常处理程序和if-else条件检查之间的区别?,c++,if-statement,exception-handling,C++,If Statement,Exception Handling,我已经在很多地方使用了if-else语句,但是我对异常处理还是新手。这两者之间的主要区别是什么 例如: int *ptr = new (nothrow) int[1000]; if (ptr == NULL) { // Handle error cases here... } 或 试试看 { int*myarray=newint[1000]; } 捕获(例外和e) { cout首先,如果new[]运算符由于未处理异常而引发异常,那么您的第一个带有if语句的代码将终止程序。您可

我已经在很多地方使用了if-else语句,但是我对异常处理还是新手。这两者之间的主要区别是什么

例如:

 int *ptr = new (nothrow) int[1000];

 if (ptr == NULL) {
     // Handle error cases here...
 }

试试看
{
int*myarray=newint[1000];
}
捕获(例外和e)
{

cout首先,如果new[]运算符由于未处理异常而引发异常,那么您的第一个带有if语句的代码将终止程序。您可以在此处检查此类情况,例如:


此外,在许多其他情况下也会引发异常,不仅是在分配失败时,而且它们的主要功能(在我看来)是将应用程序中的控件向上移动(移动到处理异常的位置)。我建议您多读一些关于异常的书,好的读物应该是“更有效的C++”斯科特·梅耶斯(Scott Meyers)在《例外》一书中有一章非常精彩。

要收集答案中的评论:

自从1998标准化后,<代码>新< /COD>在失败时不返回空指针,但抛出异常,即“代码> STD::BADYOLLC/<代码>。这与C的<代码> MalOC < /C>不同,可能是一些早期的标准前实现C++,其中代码>新< /COD>也可能返回空(我不知道,TBH)。

C++中有可能在分配失败上获得一个零指针,而不是一个异常:

int *ptr = new(std::nothrow) int[1000];
P> >总之,您所拥有的第一个代码将不会按预期工作,因为它是在C++异常的情况下进行C风格错误处理的尝试。如果分配失败,则抛出异常,如果您没有捕获到<代码> BADYOLLC/,则程序可能会被终止,程序可能会被终止。 有很多文章比较了一般错误处理、异常和返回代码,试图在这里涵盖这一主题会有很大的帮助

  • 函数返回类型不被错误处理占用,但可以返回实际值-不需要“输出”函数参数
  • 您不需要在每个函数中处理每个函数调用的返回,只需在调用堆栈的某个级别捕获异常,您就可以在那里处理错误
  • 与一个全局
    errno
    变量和一个返回的错误代码相比,异常可以将仲裁信息传递到错误处理站点

主要区别在于,使用异常处理的版本至少可以工作,而使用
if
语句的版本不可能工作

您的第一个片段:

int *ptr = new int[1000];

 if (ptr == NULL) {
     // Handle error cases here...
 }

……似乎假设<代码>新< /C>会在失败的情况下返回空指针。虽然这是一次正确的,但它并没有很长时间。对于任何合理的当前编译器,<代码>新< /C> >只有两种可能性:成功或抛出。因此,第二版与C++应该如何工作相一致。 如果确实要使用此样式,可以重写代码,使其在出现故障时返回空指针:

int *ptr = new(nothrow) int[1000];

if (ptr == NULL) {
     // Handle error cases here...
}
在大多数情况下,无论如何,您都不应该直接使用
new
——您应该真正使用
std::vector p(1000);
,然后使用它

有了这一点,我觉得有必要补充一点,对于大量的代码来说,两种方法都不做可能是最有意义的,而只是假设内存分配会成功

曾经(MS-DOS)如果您试图分配比可用内存更多的内存,那么内存分配实际上会失败是很常见的,但那是很久以前的事了。现在,事情并不是那么简单(通常)。当前的系统使用虚拟内存,这使得情况更加复杂

在Linux上,通常会发生的情况是,即使内存不是真正可用的,Linux也会执行所谓的“过度提交”。您仍然会得到一个非空指针,就好像分配成功了一样——但当您尝试使用内存时,会发生不好的事情。具体来说,Linux具有所谓的“OOM杀手”这基本上是假设内存不足是一个bug的迹象,因此如果它发生了,它会试图找到有bug的程序,并将其杀死。出于最实际的目的,这意味着您的程序可能会被杀死,其他(半任意选择的)程序也可能会被杀死

Windows与C++所期望的模型有点接近,因此如果(例如)您的代码在无人值守的服务器上运行时,分配实际上可能会失败。但是,在它失败之前,它会将机器的其余部分拖到膝盖上,疯狂地交换,这注定会导致分配成功。如果用户当时真的在操作机器,他们通常会杀死您的程序,或者杀死您的程序其他一些方法可以为代码释放足够的内存,以便相当快地获得请求的内存

在所有这些情况下,按照分配可能失败的假设进行编程都不是特别现实的。在大多数实际情况下,会发生以下两种情况之一:要么分配成功,要么程序死亡


这又回到了前面的建议:在典型情况下,您通常应该只使用
std::vector
,并假设您的分配会成功。如果您需要提供超出此范围的可用性,您只需要以其他方式来做(例如,如果进程死亡,则重新启动进程,最好使用更少内存的方式).

如前所述,原始的if-else示例仍然会从C++98开始抛出异常,尽管添加
nothrow
(编辑)应该可以使其按需要工作(返回
null
,从而触发if语句)

下面,为了简单起见,我将假设,对于if-else处理异常,我们有函数在异常时返回false

以上例外情况的一些好处,如果不是,我不知道:

  • 您知道记录/调试/错误修复的异常类型
    int *ptr = new(nothrow) int[1000];
    
    if (ptr == NULL) {
         // Handle error cases here...
    }
    
    bool someFunction() // may return false on exception
    {
       if (someFunction2()) // may return false on exception
          return false;
    
       if (someFunction3()) // may return false on exception
          return false;
    
       return someFunction4(); // may return false on exception
    }
    
    void someFunction() // may throw exception
    {
       someFunction2(); // may throw exception
       someFunction3(); // may throw exception
       someFunction4(); // may throw exception
    }