Я прочитал следующее из 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
мы можем использовать ссылку b
который связан с некоторыми Base
объект. Какой тип выражения b
? Это Base
, Потому что если бы мы создали копию упомянутого объекта, мы бы получили Base
, Это то, что известно как статический тип объекта. Тип, который написан в объявлении, простой и понятный. Кроме того, внутри main
какой тип d
? Это Derived
, по той же причине.
Но что происходит, когда вы проходите d
в foo
?
Ссылка b
привязывается к нему, что разрешено, конечно. Это «настоящий», динамический тип, это Derived
, Но foo
относится к этому с Base&
, Вот что такое полиморфное использование. Хотя функция видит один тип, на самом деле это другой тип. И из-за косвенности, это «другой» тип, который используется через механизм виртуальных функций.
Теперь давайте применим его к вашему вопросу. Метание сделает копию объекта. Тип копируемого объекта определяется выражением, которое ему дано. Поэтому, когда вы даете ему Base&
собирается создать Base
объект. Тот факт, что это действительно может быть ссылка на Derived
несущественно. Бросок исключения не является полиморфным использованием.
Какие мог быть полиморфным использованием, является catch
пункт. Если мы перехватываем по ссылке, то объект ссылки на исключение может на самом деле иметь тип, отличный от того, который у нас есть.
Других решений пока нет …