Я прочитал следующее из C++ Primer (5-е издание, раздел 18.1.1): «Когда мы выбрасываем выражение, статический тип времени компиляции этого выражения определяет тип объекта исключения». Итак, я попробовал следующий код:
#include <iostream>
class Base{
public:
virtual void print(std::ostream& os){os << "Base\n";}
};
class Derived: public Base{
public:
void print(std::ostream& os){os << "Derived\n";}
};
int main(){
try{
Derived d;
Base &b = d;
b.print(std::cout); //line 1
throw b;
}
catch(Base& c){
c.print(std::cout); //line 2
}
return 0;
}
который дает мне следующий вывод:
Derived
Base
Думаю, я понимаю, почему ожидается такой вывод: в строке 1 у нас динамическая привязка. Теперь, когда мы выбрасываем b, он основан на статическом типе b, что означает, что и статический, и динамический тип c — это Base&, поэтому мы видим результат в строке 2.
Однако, если бы я использовал указатель вместо ссылки:
int main(){
try{
Derived d;
Base *b = &d;
b->print(std::cout); //line 1
throw b;
}
catch(Base* c){
c->print(std::cout); //line 2
}
return 0;
}
вывод теперь становится:
Derived
Derived
что, по-видимому, подразумевает, что статический тип c — это Base*, а динамический тип c — Derived*, почему? Разве статический и динамический типы c не должны быть Base*?
Base*
(тип указателя). - person StoryTeller - Unslander Monica   schedule 22.10.2017