Некоторые вопросы относительно обработки исключений - PullRequest
3 голосов
/ 29 июня 2011

Пожалуйста, ознакомьтесь с демонстрационным кодом:

class myError
{
    const char* str;
public:
    myError():str(NULL) {}
    myError(const char* temp)
    {
        str = temp;
    }
    const char* what()
    {
        return str;
    }
};

class ab
{
    int x;
public:
    ab() try :x(0)
    {

            throw myError("error occured in the constructor of class ab");
    }
    catch(myError& temp)
    {
        std::cout<<"Handler no. 1 of ab constructor"<<std::endl;
    }
};

int main () try
{
    ab bb;
    cout << "Resumed execution!" << endl;
    return 0;
}
catch(myError& temp)
{
    std::cout<<"Handler below the main function"<<std::endl;
    std::cout<<"And the error is :" <<temp.what();
}

Мои вопросы:

  1. Почему только функция try обработчик блока ctor и dtor только возвращает исключение? ,

а когда вы просто выбрасываете исключение внутри ctor, его обработчик не сбрасывает объект? * 1010 т.е. *

Ctor::Ctor()
{
    try{
        throw Excep1();
    }
    catch(Excep1& temp) { 
        std::cout<<"Doesn't rethrows the exception object";
    }
}
  1. Я хочу знать, как вернуть элемент управления обратно к cout << "Resumed execution!" << endl;, после обработки брошенного объекта?

  2. почему часто говорят, что мы не должны помещать блок try-функции в dtor базового класса?

Ответы [ 3 ]

7 голосов
/ 29 июня 2011

Обычное правило заключается в том, что блок catch не перебрасывается, пока вы не попросите об этом.Как бы вы остановили распространение исключения в противном случае.Однако в случае конструктора, если что-то в списке инициализации выбрасывается, значит, у вас нет полностью сконструированного объекта;Вы ничего не можете сделать с объектом, даже не вызвать деструктор к нему.И если блок функции catch конструктора не перебрасывается, что он собирается делать, поскольку он не может просто вернуть (и оставить переменную в стеке)?

Во всех остальных случаях этоВверх выполните функцию, содержащую блок catch, чтобы узнать, что делать.Например, в случае с main вы можете написать: try {ab bb;} catch (...) {} std :: cout << "Возобновление выполнения!"<< std :: endl; </p>

Чего вы не можете сделать, так это выполнить код, в котором bb находился бы в области видимости и был бы доступен, но не был правильно построен.

Что касается того, почему выне следует помещать блок try функции в деструктор базового класса, я никогда не слышал этого правила.В общем, деструкторы не должны выбрасывать, так что нет смысла заключать их в блок try, точка.

1 голос
/ 29 июня 2011

По второму вопросу деструкторы не должны бросать точку. Рассмотрим случай, когда ваш деструктор освобождает много памяти через delete. Что произойдет, если ваш деструктор выдаст ошибку перед завершением очистки? Теперь у вас есть утечка памяти. Если ваш деструктор вызывает ошибку во время выполнения, то, возможно, у вас есть проблемы в другом месте кода, которые необходимо исправить.

0 голосов
/ 29 июня 2011

Как обычно, Херб Саттер знает и объясняет все:

Если тело обработчика содержало инструкцию "throw;" тогда блок catch, очевидно, перезапустил бы любое исключение A :: A () или B :: B (). Что менее очевидно, но ясно указано в стандарте, что если блок catch не выбрасывает (либо перебрасывает исходное исключение, либо выбрасывает что-то новое), и элемент управления достигает конца блока catch конструктора или деструктора, то Исходное исключение автоматически перебрасывается.

Подробнее в своей статье

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