2012-03-05 2 views

ответ

7

Уловка-уловка (...) не дает вам доступа к объекту исключения вообще, поэтому вопрос спорный. [Исправлено:] Повторное использование с throw; выбрасывает исходный объект. Если обработчик ловит по значению, то изменения в локальной копии не влияют на исходный, восстановленный объект. [/] Подробнее см. 15.3 (см. Раздел 17).

Проверьте некоторые связанные вопросы справа, например this one или this one и this one и this one.

+0

Если один пишет 'поймать (...) {бросить; } ', то как бы это свергнуть, по значению или по ссылке? Обратите внимание, что в этом случае не обнаружен исходный объект. – Nawaz

+0

По значению или по ссылке? – Nawaz

+0

Я особенно нахожу смелую часть, запутанную с помощью 'catch (...)': * «Rethrowing with throw; бросает исходный объект **, если исходное исключение было поймано по ссылке ** или если вызвано внутри catch-all и копия **, если исключение было поймано по значению **. "* – Nawaz

1

Бросок копирует полученное значение в определенное место реализации.
Таким образом, значение копируется при броске (это означает, что тип должен быть скопирован).

Когда вы поймаете, вы можете поймать по значению или ссылке.

catch(X val) // Catch by value 
{ 
} 
catch(Y& val) // Catch by reference 
{ 
} 

Идиоматический подход к улову заключается в том, чтобы поймать ссылку const. Это связано с тем, что если вы поймаете по значению, существует возможность разрезания, когда исключение копируется из его сохраненного местоположения в значение catch. Если вы поймаете по значению, значение будет уничтожено в конце блока catch. Копия в сохраненном месте уничтожается в конце блока try/catch, где она была схвачена (а не повторно выбрана).

Так что, когда вы ловите catch(...), ничего не происходит. Исключением остается в неуказанном местоположении, что исключение уже скопировано.

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

Примечание: вызов throw;, когда распространение исключений является ошибкой, приведет к вызову std :: terminate.

+0

как насчет 'catch (...) {throw;}', о котором спрашивает вопрос? –

+0

@MooingDuck: Извините, просто добравшись до этого. Я просто хотел сначала объяснить основную часть контекста. –

2

Вы всегда поймаете то, что бросили. Допустим, у вас есть класс исключения

class MyException { 
public: 
    int m_data; 
    MyException(int data) 
    { 
     printf("MyException::MyException() ctor\n"); 
     m_data = data; 
    } 

    MyException(const MyException & other) { 
     printf("MyException::MyException() copy ctor\n"); 
    } 

    ~MyException() 
    { 
     printf("MyException::~MyException() dtor\n"); 
    } 
}; 

1) Если вы выбросили указатель, вы получите указатель:

Пример 1:

void f() 
{ 
    throw new MyException() 
} 

void main() 
{ 
    try{ 
     f(); 
    }  
    catch(MyException * ex) // You WILL catch the pointer 
    { 
     delete ex; // You should delete the exception object 
    } 
    catch(MyException & ex) // You WILL NOT catch the pointer 
    { 
    } 
} 

Пример 2:

void main() 
{ 
    try{ 
     f(); 
    } 
    catch(...) // You WILL catch the pointer, but will be unable to access it 
    { 
     throw; // You are rethrowing the pointer 
    } 
} 

2) Если вы бросили объект, вы будете ловить ссылку на него:

Пример 1:

void f() 
{ 
    printf("f BEGIN\n"); 
    throw MyException(1); // MyException ctor is called 
    printf("f END\n"); 
} 

void main() 
{ 
    printf("main BEGIN\n"); 

    try 
    { 
     f(); 
    } 
    catch(MyException & ex) // You WILL catch a reference to created object 
    { 
     printf("catch MyException: %d\n", ex.m_data); 
    } // MyException dtor is called here!! 

    printf("main END\n"); 
} 

Следующий вывод производится :

main BEGIN 
f BEGIN 
MyException::MyException() ctor 
catch MyException: 1 
MyException::~MyException() dtor 
main END 

Пример 2:

void main() 
{ 
    try 
    { 
     f(); 
    } 
    catch(...) // You WILL catch a reference to created object, 
       //but will be unable to access it 
    { 
     throw; // You throw the reference 
    } 
} 
Смежные вопросы