c++ - 异常表达式创建的异常对象的类型

标签 c++ exception dynamic error-handling static-typing

我从 C++ Primer(第 5 版,第 18.1.1 节)中读到以下内容:“当我们抛出一个表达式时,该表达式的静态编译时类型决定了异常对象的类型。”

作者所说的“异常对象的类型”是指异常对象的动态类型还是静态类型

这是一个相关的问题: Static type of the exception object

最佳答案

我认为您一般在掌握动态类型和静态类型方面遇到困难。因此,让我们解决这个问题,暂且不考虑异常(exception)情况。

首先,静态类型和动态类型何时发挥作用?答案是运行时多态性。现在,虽然您可能听说过“多态类型”这个词,但您应该知道根本没有这样的东西。类型不是多态的。

但是它们可以以多态方式使用!这种区别很重要,我希望您很快就会明白为什么。让我们看一个简单的案例研究:

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 中,我们可以使用绑定(bind)到某个 Base 对象的引用 b。表达式 b 的类型是什么?它是 Base。因为如果我们要创建引用对象的拷贝,我们会得到一个 Base。这就是所谓的对象的静态类型。写在声明中的类型,简单明了。此外,在 main 内部,d 的类型是什么?出于同样的原因,它是 Derived

但是当你将 d 传递给 foo 时会发生什么?

引用 b 绑定(bind)到它,这当然是允许的。它是“真实的”,动态类型,是 Derived。但是 foo 使用 Base& 引用它。这就是多态用法。尽管该函数看到一种类型,但它实际上是另一种类型。由于间接性,它是通过虚函数机制操作的“其他”类型。

现在让我们将其应用到您的问题中。 throw 将复制该对象。复制对象的类型由给定的表达式决定。所以当你给它一个 Base& 时,它会创建一个 Base 对象。它可能真的是对 Derived 的引用这一事实无关紧要。抛出异常不是多态用法。

可能 是多态用法,是 catch 子句。如果我们通过引用捕获,那么所引用的异常对象实际上可能与我们拥有的引用具有不同的类型。

关于c++ - 异常表达式创建的异常对象的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46872347/

相关文章:

c++ - 使用 Boost.Qi 实现递归语法

java - 为什么我收到 HttpHostConnectException

c - 是否可以在编译期间动态创建等效的limits.h宏?

C++ 使用运算符重载构建双面树 - 什么是好的内存解决方案?

c++ - ^ 在 bool GetDeviceInformation(String ^ port, LibCECConfiguration ^configuration, uint32_t timeoutMs) 中是什么意思

php - Laravel 5.3 未经授权() AuthenticationException fatal error

java - 使用诸如 ".lambda$null$2"& 和 "$$Lambda$"之类的 lambda 解释 Java 堆栈跟踪

安卓通知动态图标

android - 从另一个 apk 动态加载资源(布局)

c++ - NoDecodeDelegateForThisImageFormat 使用 ImageMagick 读取 .png 文件时出错