Можно ли установить пользовательский обработчик для случаев, когда выбрасывается bad_cast? - PullRequest
0 голосов
/ 16 марта 2012

В случае сбоя dynamic_cast<SomeType&> выдается исключение 1002 *.В моем коде есть отдельная иерархия исключений, и bad_cast не входит в эту иерархию, поэтому мой код не будет обрабатывать bad_cast.Могу ли я получить какое-то другое исключение вместо этого?

Я имею в виду, что я хотел бы написать собственный обработчик, такой как:

void OnBadCast()
{ 
    throw MyException( "Bad cast" );
}

и каким-то образом зарегистрировать его в C ++ runtime

RegisterMyBadCastHandler( &OnBadCast );

так, что этот обработчик вызывается вместо bad_cast, брошенного.

Возможно ли это?

Ответы [ 3 ]

1 голос
/ 16 марта 2012

Плохое приведение обычно указывает на ошибку в программе (например, вне диапазона или нехватки памяти), и, следовательно, не должно быть обнаружено вообще (или, возможно, на верхнем уровне).Если вы хотите выполнить ветвление в случае успеха dynamic_cast, тогда проверьте на нулевое значение в форме указателя:

if (T* p = dynamic_cast<T*>(some_ptr))
{
    // Do something with p
}

Если вам нужен специальный обработчик, лучшее, что вы можете сделать, это, таким образом, следующее:

template <typename T, typename U>
T& polymorphic_cast(U& x)
{
    if (T* p = dynamic_cast<T*>(&x)) return *p;

    my_handler();
}

где my_handler должен убить программу (и, возможно, зарегистрировать ошибку).Но здесь вы можете использовать простую форму dynamic_cast<T&>, позволить std::bad_cast всплыть и войти в систему на верхнем уровне.Это также лучше работает с отладчиками, которые можно настроить так, чтобы они останавливались в точке сбоя приведения.

Случаи, которые вы описываете в своих комментариях, достаточно редки, чтобы заслуживать особого рассмотрения, например ::

if (auto p = dynamic_cast<foo*>(q)) { do_something(); }
else { throw bail_me_out_of_here(); }

может использоваться для указания стратегу, работающему в верхнем течении, что ему следует попробовать другой метод.

1 голос
/ 16 марта 2012

Не думаю, что вы можете изменить это поведение.

То, что вы могли бы сделать, это использовать своего заклинателя, однако:

template<class T, class E> T myCast(E expr)
{
    try
    {
        return dynamic_cast<T>(expr);
    }
    catch(std::bad_cast e)
    {
        // custom handler
    }
};
0 голосов
/ 16 марта 2012

Вам не нужно иметь исключения в той же иерархии для их обработки. По крайней мере, не в VC ++. Если вы просто беспокоитесь об обработке различных типов ошибок, сделайте что-то вроде ниже. Если этого ответа недостаточно, остальные превосходны, учитывая ограничения, с которыми вы работаете, хотя обратите внимание на то, когда выдается bad_cast, а когда нет. http://answers.yahoo.com/question/index?qid=20071106101012AAggZAk

#include <iostream>
#include <exception>

using namespace std;

class my_exception {
public:
    explicit my_exception() {};
    const char* msg() const { return "my_exception"; }
};

int main()
{

    try {

        // comment either line.
        throw std::exception("std::exception");
        throw my_exception();

    }
    catch (const std::exception& e )
    {
        cout << e.what() << endl;
    }
    catch (const my_exception& e)
    {
        cout << e.msg() << endl;
    }

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...