C++:Генерация производного класса по ссылке не работает при перехвате базового класса

Я хочу генерировать собственные исключения с помощью базового класса Exception. Существует виртуальный метод print, который будет перезаписан подклассами. Я ловлю только тип Exception&и использую print, чтобы получить конкретную ошибку. Проблема в том, что когда я выбрасываю ссылку на подкласс, она обрабатывается так, как если бы это был базовый класс.

Вот пример.:

#include <iostream>
using namespace std;

class Exception
{
    public:
        virtual void print()
        {
            cout << "Exception" << endl;
        }
};

class IllegalArgumentException : public Exception
{
    public:
        virtual void print()
        {
            cout << "IllegalArgumentException" << endl;
        }
};

int main(int argc, char **argv)
{
    try
    {
        IllegalArgumentException i;
        Exception& ref = i;

        cout << "ref.print: ";
        ref.print();

        throw ref;
    }
    catch(Exception& e)
    {
        cout << "catched: ";
        e.print();
    }
}

Результат этого примера::

ref.print: IllegalArgumentException
catched: Exception

Использование ссылки должно привести к использованию метода printиз производного класса. Внутри блока try ссылка использует его. Почему перехваченный Exception&не ведет себя как IllegalArgumentExceptionи как добиться такого поведения?

Следующий код, похоже, делает то, что должен :

try
{
    IllegalArgumentException i;
    Exception* pointer = &i;

    throw pointer;
}
catch(Exception* e)
{
    cout << "pointer catched: ";
    e->print();
}

, но не становится ли указатель недействительным вне области действия блока try? Тогда было бы рискованно делать это, и если я выделяю память в куче, чтобы обойти эту проблему, я несу ответственность за удаление внутри блока catch, что тоже некрасиво. Так как бы вы решили проблему?

11
задан user1286875 22 March 2012 в 21:17
поделиться