I just came up with a problem when I learned about using Exceptions. The code is as follows.
// exception constructor
#include <iostream>  // std::cout
#include <exception> // std::exception
#include <cxxabi.h>
#define PRINT_TYPENAME(f) std::cout << abi::__cxa_demangle(typeid(f).name(), 0, 0, &status) << std::endl;
struct ooops : std::exception
{
    const char *what() const noexcept { return "Ooops!\n"; }
};
int main()
{
    ooops e;
    std::exception *p = &e;
    // demangle the typeid
    char *realname;
    int status;
    PRINT_TYPENAME(p);
    PRINT_TYPENAME(*p);
    try
    {
        throw e; // throwing copy-constructs: ooops(e)
    }
    catch (std::exception &ex)
    {
        std::cout << ex.what();
    }
    try
    {
        throw *p; // throwing copy-constructs: std::exception(*p)
    }
    catch (std::exception &ex)
    {
        std::cout << ex.what();
    }
    return 0;
}
The output is:
std::exception*
ooops
Ooops!
std::exception
It seems that *p has the type of the derived class. However, when std::exception &ex=*p, the type_id.name() of ex becomes the base class rather than the derived class.
Since *p and ex have the same type. I feel confused about why the type of ex differs between the two try-catch sentences.
Can someone tell me the reason? Thanks for the help.
 
    