Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.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++ 我什么时候需要使用投掷和回击?_C++ - Fatal编程技术网

C++ 我什么时候需要使用投掷和回击?

C++ 我什么时候需要使用投掷和回击?,c++,C++,我看到一个函数,它使用throw返回一些东西 在问这个问题之前,我做了一些研究,在这里,关于throw,我没有发现太多 如果有人能告诉我什么时候使用throw返回什么,什么时候使用正常的return语句,那就太棒了。throw不用于返回任何值,它用于引发异常,即,如果您认为程序中的某个条件将导致运行时错误或故障,那么您将引发一个有助于避免和处理此类运行时错误的异常。Return用于从函数和值返回调用函数。使用throw返回结果在深度嵌套递归中非常有用。而不是退出每一个通话级别,你可以直接回到这个

我看到一个函数,它使用
throw
返回一些东西

在问这个问题之前,我做了一些研究,在这里,关于
throw
,我没有发现太多


如果有人能告诉我什么时候使用
throw
返回什么,什么时候使用正常的
return
语句,那就太棒了。

throw不用于返回任何值,它用于引发异常,即,如果您认为程序中的某个条件将导致运行时错误或故障,那么您将引发一个有助于避免和处理此类运行时错误的异常。Return用于从函数和值返回调用函数。

使用
throw
返回结果在深度嵌套递归中非常有用。而不是退出每一个通话级别,你可以直接回到这个目标的最高级别通话。我认为在大多数其他情况下,它都太低效(因为异常被优化用于故障处理),太过不常规甚至无法考虑。

抛出可用于处理异常。请看以下代码:

#include <iostream>
#include <stdexcept>

int i = 0;

int main() {
    if(i == 0) {
       throw std::runtime_error("Error, I is equal to 0");
    }
    std::cout << "I is not equal to zero, program finished.";
}
但是,如果删除了throw语句,异常将不起作用,请继续尝试

另一方面,使用Return是为了在执行一个函数后,您能够知道该函数做了什么。请看以下代码:

#include <iostream>
#include <stdexcept>

int i = 0;

int errorOccured() {
  return true;
}

int main() {
  bool x = errorOccured();

if(x == true) {
  std::cout << "Major error occured";
}

else if(x == false) {
  std::cout << "No error occured";
  }
}
#包括
#包括
int i=0;
int errorOccursed(){
返回true;
}
int main(){
bool x=发生错误();
如果(x==true){

std::cout
return
是返回计算值、类成员引用、状态信息(例如枚举值)、简单的成功/失败信息和、和的最简单且在许多情况下也是最有效的方法。因此,这是评估函数值的最常用方法

throw
另一方面(就像Alf已经回答的那样)处理
异常
,正如名字已经非常清楚地指出的那样:)正常控制流的异常:“非常重要的事情(通常是不好的事情)发生,这需要即时处理,我无法继续正常的处理流程,必须立即抛出异常。”。原因有时可能是程序中的灾难性和不可恢复状态,但绝不总是如此。例如,套接字失去连接是很常见的,而不是灾难性的-但也可能是引发异常的原因,因为套接字代码可能无法继续计算

异常通常比通常的返回值更难处理,也更难集成到程序设计中,正如其他人所说,它们比简单的返回值效率更低,但它们有很多好处

它们可以从调用函数堆栈中的任何位置捕获 假设你用一个游戏引擎(比如食人魔)编写了一个游戏,这个引擎使用了direct X接口。现在DirectX接口中发生了一些很深很深的事情,这阻碍了引擎的正常工作。 此函数的错误处理(调用堆栈中可能有8-10个调用),它不能再正常工作了,如果使用正常的返回值(对于引擎程序员和游戏程序员都是如此)几乎是不可能的。因此,在这种情况下,如果没有异常,选择的方法将是非标准化的错误处理程序-非常类似于异常,但不具有强大的可能性异常。下面是一个关于如何处理异常错误的实际示例(请忽略函数的真正用途,这只是为了说明以下原则:

        try 
        {
            mHOQList[mCurrentFrame]->endOcclusionQuery();
        } catch( Ogre::Exception& e )
        {
            if( e.getNumber() == Exception::ERR_RENDERINGAPI_ERROR
            && stdEx::string(e.getDescription()).beginsWith( "End occlusion called" ))
            {
                // a device lost occurred during our occlusion query. Simply ignore it.
                return true;
            }
            else
                throw;

        }
我们在这里做一个阻塞查询,我们知道当操作过程中发生“设备丢失”事件时,该查询无法继续。因此,我们将其放在try/catch子句中。当
endoclusionquery()
中一切正常时,
catch()
将永远不会被调用,并且一切正常。 如果抛出异常,我们首先检查是否可以处理它。我们检查异常的数量及其描述。如果这些信息有特定的值,我们知道这是一个良性错误,我们可以安全地忽略它并继续下一帧。如果我们不知道如何处理它,我们只需
抛出;
,这样就可以处理t他超越了调用层次结构中较低的
catch()

可以对其进行选择性评估。 上面的示例将捕获并处理类型为
Ogre::Exception
的异常,但不会捕获其他异常。std::Exception或其他异常类型不会被捕获。例如,
endoclusionquery()
在我们自己的代码中调用回调,然后回调也会进入异常状态并抛出。我们会让此异常通过,并将其留给调用层次结构的较低(或较高)级别来处理

它们可以回收。 在本例中,我们使用
throw;
重新抛出并将处理传递给调用层次结构中的较低级别

它们可以存储,甚至可以重新抛出到单独的线程中 想象一个有数百个工作线程的库,以及一个协调这些线程的管理线程。由于异常绑定到单个线程,因此管理线程永远无法捕获来自工作线程的异常。但是工作线程可以捕获自己的异常,并在可能的情况下处理它们或存储它们,将它们传递给manager线程,在该线程中它可以被回收并由管理器线程处理

它们可以被抛出构造函数中 构造函数没有返回值,因此不可能用返回值检查其成功性。状态成员是可能的,但很尴尬——它们往往会被忽略。因此处理构造函数中错误的首选方法是抛出(当然是记录在案的行为)。另请参阅

try { mHOQList[mCurrentFrame]->endOcclusionQuery(); } catch( Ogre::Exception& e ) { if( e.getNumber() == Exception::ERR_RENDERINGAPI_ERROR && stdEx::string(e.getDescription()).beginsWith( "End occlusion called" )) { // a device lost occurred during our occlusion query. Simply ignore it. return true; } else throw; }