Za blokiem
try
można umieścić kilka następujących po sobie
bloków
catch. Jeśli w takiej sytuacji nastąpi zgłoszenie
wyjątku, to podczas poszukiwania odpowiedniej procedury obsługi
będzie sprawdzany typ wyjątków deklarowany w nagłówkach przez
kolejne bloki
catch. Jeśli (po ewentualnej konwersji niejawnej,
jak w poprzednim przykładzie) znaleziony zostanie odpowiedni typ, to ta
właśnie fraza
catch
 zostanie użyta i na tym obsługa tego
wyjątku zakończy się: pozostałe bloki
catch
 zostaną już
zignorowane, nawet jeśli jest wśród nich taki o bliższym dopasowaniu
typu parametru z typem wyjątku. Konwersje w górę są wykonywane tylko
dla argumentów obiektowych. Na przykład program
      1.  #include <iostream>
      2.  using namespace std;
      3.  
      4.  int main() {
      5.      try {
      6.          throw 7;
      7.      }
      8.      catch(double) { cout << "double" << endl; }
      9.      catch(int   ) { cout << "int   " << endl; }
     10.  }
Dla wyjątków typu obiektowego konwersja w górę będzie
jednak zastosowana
      1.  #include <iostream>
      2.  using namespace std;
      3.  
      4.  class A { };
      5.  class B : public A { };
      6.  
      7.  int main() {
      8.      try {
      9.          throw B();
     10.      }
     11.      catch(A) { cout << "A" << endl; }
     12.      catch(B) { cout << "B" << endl; }
     13.  }
    cpp> g++ -pedantic-errors -Wall -o hierob hierob.cpp
    hierob.cpp: In function `int main()':
    hierob.cpp:12: warning: exception of type `B' will be
                        caught by earlier handler for `A'
    cpp> ./hierob
    A
Kompilator wypisał tu ostrzeżenie, bo w tym przykładzie
druga fraza
catch
 w ogóle nie jest osiągalna.
To samo obowiązuje dla wyjątków wskaźnikowych; program
      1.  #include <iostream>
      2.  using namespace std;
      3.  
      4.  struct A {
      5.      const char* info() { return "A*"; }
      6.  };
      7.  
      8.  struct B : A {
      9.      const char* info() { return "B*"; }
     10.  };
     11.  
     12.  int main()
     13.  {
     14.      try {
     15.          throw new B;
     16.      }
     17.      catch(A* a) { cout << a->info() << endl; }
     18.      catch(B* b) { cout << b->info() << endl; }
     19.  }
    cpp> g++ -pedantic-errors -Wall -o hier1 hier1.cpp
    hier1.cpp: In function `int main()':
    hier1.cpp:18: warning: exception of type `B*' will be
                       caught by earlier handler for `A*'
    cpp> ./hier1
    A*
Tak więc, jeśli klasa 
B
 dziedziczy z 
A, wyjątek jest
typu
B
 (lub
B*), a fraza
catch
 deklaruje
typ 
A
 (lub
A*
 lub
A&), to wyjątek zostanie
wychwycony przez tę frazę, jeśli:
Czasem na samym końcu listy fraz catch umieszcza się taką frazę z trzema kropkami zamiast parametru
       catch(...) {
           // ...
       }
Oznacza ona „wyłap każdy wyjątek, niezależnie od jego
typu”.
T.R. Werner, 21 lutego 2016; 20:17