我们每天都在谈论异常处理。我们都知道它是在执行过程中遇到一些意想不到的情况而产生的。
这里有几个问题:
什么是异常?它最低级的内存组成是什么?在 .NET 中,我可以将其视为某种异常类型 的对象实例。在本土世界,它是由什么制成的?一些数据结构?
如果程序员没有明确抛出异常,那么谁来创建异常,如下面的代码所示?它是某些语言运行时提供的支持的一部分吗?
SomeException e = new SomeException(); 扔 e;
异常工作范式是什么?当发生某些错误时,语言运行时会创建相应数据结构/类型的实例来表示错误的详细信息,这是真的吗?
我们如何知道运行时所有可能的意外情况,从而创建足够的异常数据结构/类型来表示它们?
感谢您的回复。
最佳答案
您问题的答案在很大程度上取决于我们谈论的是什么语言。
C 没有异常(exception),尽管有专有语言扩展。
C++ 有一种方法可以在您的代码中的任何位置“抛出”一个任意对象并“捕获”它在调用堆栈的更高位置。
C# 有一种方法可以“抛出”从 System.Exception
派生的对象 并且还“捕获”来自堆栈较高位置的那些。此外,我认为 .NET 运行时会在每次抛出异常时报告一些问题。
- What is an exception? What's its most low-level in-memory composition? In .NET, I can think of it as some object instance of some exception type. In the native world, what is it made of? Some data sturcures?
在 C++ 中,它只是一个任意对象,与代码中的其他对象一样创建:
throw 42; // throws an int object
throw "blah"; // throws a char[5] object
throw std::string("arg!"); // throws a std::string object
throw my_type(42); // throws a my_type object
throw std::exception("doh!"); // throws a std::exception object
抛出的异常与catch
的匹配短语与重载函数的匹配非常相似。 (一个很大的区别在于,catch 短语是有序的。也就是说,第一个完全匹配的将“获胜”并捕获对象。然而,重载函数必须始终提供明确的最佳匹配。)
- Who create the exception if the exception is not thrown explicitly by the programmer as the following code shows? Is it part of the support that certain language runtime provides?
在 C++ 中,异常几乎只能从代码中抛出。它可以是您自己的代码、其他人的代码、某些库的代码或标准库的代码。但通常必须有一个 throw
某处声明。有一些异常(exception)(没有双关语意),比如 std::bad_alloc
由 new
抛出(这可能是从代码中的 throw
语句中抛出的,但我认为不必如此)和 std::bad_cast
, 从 dynamic_cast<>
抛出. (此外,预计明年推出的下一个标准 C++1x 允许异常以某种方式跨线程边界,这可能需要标准库实现者找到一种方法来在一个线程中存储异常并从另一个线程重新抛出它。但我'我对此很模糊。)
SomeException e = new SomeException(); throw e;
在 C++ 中,您可以,但您很少会想要抛出指针。你要么做
SomeException e; throw e;
或
throw SomeException();
- What is the exception working paradigm? Is it true that when some error happens, an instnace of the corresponding data structure/type is created by the language runtime to represent the details of the error?
C++ 标准库抛出异常的地方很少,但除此之外我只能想到上面提到的两个特性(加上 C++1x 中的一个)运行时“自己”抛出异常。
- How could we know all the possible unexpected situations at runtime and thus create enough exception data structures/types to represent them?
通常只抛出派生自 std::exception
的类的对象在 C++ 中,尽管我遇到过使用它们自己的异常类层次结构的代码,该层次结构并非 Root 于 std::exception
.标准库中异常层次结构的问题在于它的类是非虚拟地从彼此派生的,这使得你自己的异常层次结构不可能使用多重继承来隐藏标准库中的异常层次结构。 (就像拥有自己的 OutOfRange
继承自 std::out_of_range
的异常类型和继承自 MyException
的异常基类 std::exception
一样。)
C++处理异常的方式主要基于以下原则:
- 以使其不受任何时候抛出的异常影响的方式编写代码。使用 RAII和其他技术来实现这一点。
- 只在您可以采取措施的地方捕获异常。
- 仅在特殊情况下抛出异常。不要将它们用于控制流。 (C++ 异常的设计目标是让供应商能够实现它们,以便在非异常情况下以异常情况为代价最大限度地减少开销。)
关于c# - 什么是异常(exception)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4085577/