2016-02-20 2 views
2

У меня есть несколько вопросов об исключении исключений из C++. Из того, что я знаю о них ...C++ - Несколько вопросов об исключениях исключения

Исключение может быть выбрано из функции main(). Любой блок кода, который может бросить исключение в основной функции() должен быть окруженным попытаться поймать заявления следующего

void foo(//args) { 
    if (...) { 
     throw "Error reached"; 
    } ... 

    int main() { 
    ... 
    try { 
     //Code that can throw an excpetion 
    } catch(const char* msg) (
     cerr << msg << endl; 
    } 
    ... 
    } 

В приведенном выше примере, почему аргумент улов константного символа *. Не допускает ли C++ строки? Кроме того, можно ли исключить исключение, которое не является const char *, как int? или символ?

Выбрасывает исключение в foo, завершает функцию foo?

Есть ли случаи, когда вы могли бы поставить заявления try и catch в ту же функцию, что и бросок?

Извините, если это основные вопросы. Благодаря SO

+0

Извините, я хотел сказать, что исключение, которое выбрано в foo «Ошибка достигнуто», является строкой или константой char *, потому что я думаю, что это то, что мне нужно включить в оператор catch в качестве параметра. –

+1

Вы можете отредактировать свой вопрос, а не предоставлять ошибки в комментариях. –

+0

@The_Questioner Добавлен пример ниже, HTH. – mbw

ответ

5

почему аргумент улове константный символ *

Потому что вы бросили строковый литерал, который распадается на const char*. Короче говоря, вы поймаете то, что бросаете.

Не допускает ли C++ строки?

Это так, но чтобы поймать строку, вам нужно бросить строку на первое место.

возможно бросить исключение, которое не константный символ *,

Вы можете бросить буквально все. Это хорошая идея бросить специальные классы исключений, такие как std::exception и полученные из него.

Выбрасывает исключение в foo, завершает функцию foo?

Да, это так.

Есть ли случаи, когда вы могли бы поставить заявления try и catch в ту же функцию, что и бросок?

Если вы хотите, вы можете это сделать. Не так много случаев, когда делать это - хорошая идея.

Похоже, вам нужно получить хорошую книгу и прочитать главу об исключениях. Тем временем this super-FAQ entry может вам помочь/

+0

Спасибо за это. У меня есть следующий вопрос, если вы не возражаете. Если какой-либо строковый литерал я бросаю распады в const char *, то как я могу нарисовать строку? После этого я изучу некоторые хорошие книги на C++. –

+0

@The_Questioner 'throw std :: string (" some string ");' –

+1

Или 'throw 'some string' s;' !! –

2

Вы можете бросить объект любого типа.

EDIT: (Надеюсь, я получил это прямо сейчас) То, что вы сделали это бросить C-строку, которая имеет тип const char[13] в этом случае. C-массивы будут распадаться на указатели на их первый элемент, в этом случае указатель типа const char*.

Как правило, вы хотите бросить предопределенный объект исключения. Их можно найти в заголовке <stdexcept> и являются производными от базового класса std::exception. Производные классы исключений, являются, например, std::logic_errorstd::range_error, std::bad_alloc и т.д.

Их конструкторы принимают строку в качестве аргумента, так что вы можете, к примеру

throw std::logic_error{"Negative values not allowed."}; 

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

catch(std::exception &e) // capture reference to base class 
{ 
    std::cout << e.what() << '\n'; // what() of derived is called, since virtual 
} 

Если исключение ловится, так называемый стек разматывания происходит. Затем вы можете локально решить проблему с ошибкой или переустановить исключение. Только когда исключение бросается и никогда не попадает, std :: terminate() называется программой, прерванной.

Вы можете указывать утверждения try/catch в любом месте. Однако помните, что на самом деле означает термин «исключение». Случаи, которые легко справляются с использованием простого условного выражения if (n < 0) break; или что-то в этом роде, не нуждаются в обработке исключений. Особенно, если вы можете реально ожидать такого нежелательного состояния, чтобы быть правдой часто. Тогда это не что-то «исключительное».

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

Так вы можете положить несколько заявления об уловах непосредственно после того, как попытка заявления, вы можете начать иметь дело с более конкретными ошибками, или просто поймать ничего через catch(...) { //... }.

Это все описано очень подробно (в том числе указатели на когда это и когда не использовать его, в C++ FAQ

EDIT:. Вот пример, который использует заявления/улова попробовать . Тем не менее, не является объект перехвате исключения, но ИНТ (ошибка) Просто чтобы показать, что вы действительно можете бросить/поймать все что угодно Пусть process_several_files() функция где-то вложенная в коде:..

std::vector<std::string> process_several_files(std::vector<std::string> const& files) 
{ 
     std::vector<std::string> contents{}; 
     contents.reserve(files.size()); // files contains file names from user input 
     for (auto const& file : files) 
     { 
      try 
      { 
       contents.emplace_back(get_file_contents(file.c_str())); // A "C like" function. get_file_contents() will throw "errno", if a file does not exist 
      } 
      catch(int err) 
      { 
       std::cerr << "***Error while opening " << file << " : " << std::strerror(err) << "***\n"; 
       continue;     // "scope" didn't change, just keep iterating! 
      } 
     } 
     return contents; 
} 
+2

Строковый литерал не имеет тип 'char *'. И это не тип 'const char *'. –

+0

Пила, что буквально первая секунда, которую я разместил. Извините. – mbw

+0

Вот почему это все еще неправильно?;) –

Смежные вопросы