Q1: yes. you can throw any type, not necessary types that inherit from std::exception.
you can write throw 1;
to throw and int or throw "hello";
to throw a char*
, both of which do not inherit from std::exception
. this is however considered bad practice because the user of the class can't expect you to throw anything. If you don't want to inherit from std::exception
what you usually do is create your own exception hierarchy.
Q2: catching an exception by value (2nd option) is a bad practice because you force the exception instance to be copied and in that possibly performing allocations which may cause further exceptions.
Using the first option suggest you intend to change e
in the catch block which is also something you'd probably like to avoid because exceptions are usually maintained immutable after creation. The only thing that is left is the third option.