异常表达式创建的异常对象的类型
The type of the exception object created by an exception expression
我从C++Primer(第5版,第18.1.1节)中读到以下内容:"当我们抛出一个表达式时,该表达式的静态编译时类型决定了异常对象的类型。">
作者所说的"异常对象的类型"是指异常对象的动态类型还是静态类型?
这里有一个相关的问题:异常对象的静态类型
我认为您在一般情况下难以掌握动态和静态类型。因此,让我们来解决这个问题,并将例外情况放在边线上。
首先,静态和动态类型什么时候开始发挥作用?答案是运行时多态性。现在,虽然你可能听说过"多态类型"这个词,但你应该知道根本没有。类型不是多态的。
但它们可以被多晶型地使用!这种区别很重要,我希望你很快就会明白原因。让我们来看一个简单的案例研究:
struct Base {
virtual void print() const { std::cout << "Base"; }
};
struct Derived : Base {
void print() const override { std::cout << "Derived"; }
};
void foo(Base& b) {
b.print();
}
int main() {
Derived d;
foo(d);
}
在foo
中,我们可以使用绑定到某个Base
对象的引用b
。表达式b
的类型是什么?是Base
。因为如果我们要创建引用对象的副本,我们会得到一个Base
。这就是所谓的对象的静态类型。在声明中编写的类型,简单明了。此外,在main
内部,d
的类型是什么?出于同样的原因,它是Derived
。
但是,当您将d
传递给foo
时会发生什么?
引用b
与它结合,这当然是允许的。它是"真实的",动态的类型,是Derived
。但是foo
用Base&
来指代它。这就是多态用法。即使函数看到一种类型,但实际上它是另一种类型。由于间接性,它是通过虚拟函数机制操作的"其他"类型。
现在让我们将其应用于您的问题。投掷将生成对象的副本。复制对象的类型由它所给定的表达式决定。因此,当您给它一个Base&
时,它将创建一个Base
对象。事实上,它可能真的是对Derived
的引用,这是无关紧要的。引发异常不是多态用法。
可能是的多态用法,是catch
子句。如果我们通过引用捕获,那么被引用的异常对象实际上可能与我们的引用具有不同的类型。
- 您应该在什么时候创建自己的异常类型
- 为什么标准不允许通过引用捕获不完整的异常类型?
- 如何修复"ctypes"。参数错误:参数 2:<键入"异常.类型错误">:RaspberryPi 中的错误类型"错误
- 提出异常并处理C 的某些异常类型的正确方法是什么?
- 无法在谷歌测试中检查异常类型
- QT创建者和MSVC-忽略调试时特定的异常类型
- 如何捕获除使用 GDB 的异常类型之外的所有异常类型
- 异常是否应具有标志/消息,或者每个错误应具有异常类型
- 如何在不同的上下文(例如线程)中保留原始异常类型信息
- std::rethrow_exception和抛出的异常类型
- 捕获派生异常类型在 Clang/MacOS X 上失败
- C++:检查是否在没有外部库的情况下抛出了某个异常类型
- 如何猜测 libpqxx C++库函数引发的异常类型
- 获取异常类型
- catch语句如何在没有反射的情况下识别异常类型
- 我们应该使用标准库中的异常类型吗?
- 为什么我的程序从异常中崩溃,即使我捕获了异常类型
- 如何在Mac上从c++程序中自动获取异常类型和消息
- close()抛出什么异常类型
- c++中无法捕获异常:无法识别异常类型