Why in the divisionNum method after the throw operator, the work of the try block does not stop and does not proceed to the execution of the catch block code, but quietly goes to the line cout << num1 / num2 ?

 #include <iostream> #include <string> using namespace std; class P { public: int num1, num2; P(int _num1, int _num2) { num1 = _num1; num2 = _num2; } void sumNum() { cout << num1 + num2 << endl; } void divisionNum() { if (num2 == 0) { throw "PPPPP"; } cout << num1 / num2; } ~P() {} }; int main() { setlocale(LC_ALL, "rus"); P obj2(10, 0); try { obj2.divisionNum(); } catch (string s) { cout << s << endl; return 1; } system("pause"); } 
  • If you write like this, then the throw string("PPPPP"); will be caught throw string("PPPPP"); i.e. There is no implicit type conversion (from char* to std::string ). In general, it is a bad practice to throw an exception with a class that can generate it itself (I’m std::string about std::string ), use the appropriate classes, for example, std::exception . - StateItPrimitive
  • How did you decide that cout << num1 / num2; ? - αλεχολυτ

4 answers 4

Try to put in place of string s ....

 catch (...) 

From MSDN ...

The throw expression throws an exception, i.e. creates it. The block of code after the catch clause is an exception handler. This is a handler that catches the exception thrown IF THE TYPES IN THE EXPRESSIONS throw and catch are COMPATIBLE.

On good, it would be necessary, that such type was a derived class from a class exception. Since you did not use this type, but you still need to catch an exception, we read the same MSDN further.

If the catch statement specifies an ellipsis (...) instead of a type, the catch block handles ALL TYPES OF EXCEPTIONS.

Update

From MSDN (I don’t need to explain what it is, I think) The expression throw throws an exception, i.e. creates it. The block of code after the catch clause is an exception handler. This is a handler that catches the exception thrown IF THE TYPES IN THE EXPRESSIONS throw and catch are COMPATIBLE.

On good, it would be necessary, that such type was a derived class from a class exception. Since you did not use this type, but you still need to catch an exception, we read the same MSDN further. If the catch statement specifies an ellipsis (...) instead of a type, the catch block handles ALL TYPES OF EXCEPTIONS.

So, answering your question about whether a crutch (...) is in this particular case is not.

  • Thank you, it works that way. Do not tell me why "Just changed string s to char * s" - a crutch, and catch (...) not? And the main "misunderstanding" at the moment is "And use numerals in throw.", Why should you not leave throw empty, if after it you can still write a random number that is not used further? - Aselmo
  • @Aselmo As for numbers, take a look at this code and the result of its work. This example shows how you can use numerals to determine what caused the exception. Your example, I'm not even sure that it will compile everywhere. - Max ZS
  • @Aselmo As a big thank you, voting for an answer is used on this resource and / or if satisfied with the answer, it is ticked. If the answer is not complete, then you can report it and topikaster will gladly add it. You can also vote for comments. - Max ZS
  • Far from the best solution. This is rather the ultima ratio, when you just need to carefully complete the program, but so you DO NOT GET INFORMATION about what actually happened. catch(...) is a “despair” solution :) - Harry
  • @Harry Have you read the comments right before yours? :) Not? Not necessary? :) Although it is probably part of my fault that I did not transfer all the information from the comments in response ... - Max ZS

Let me give you some tips. For starters, it is better to generate exceptions by value (not as a pointer), but to intercept them as a link. An added bonus is that

 catch(const base&) 

will intercept both the base exception and its derivatives. From here, by the way, is another tip - first write catch for derived exceptions, and then for basic ones, well, and the last catch(...) .

Secondly, I would advise using std::exception as the base exception, and using your derivatives, or using a ready-made hierarchy like logic_error , domain_error and others like them is a question that I haven’t yet seen a convincing unambiguous answer.

But to use all kinds of built-in types - like int , char* , etc. - Better not. Not that it is forbidden, but then it will be difficult to get through your own exceptions ...

Well, you have already found an error in yourself - there is no implicit type conversion in catch ...

And yet - in your original version the dividing line is in fact NOT executed; you wrote it for nothing; most likely, you just get a program crash - due to an uncaught exception.

    It seems to figure out if suddenly someone will need:

     #include <iostream> #include <string> using namespace std; class P { public: int num1, num2; P(int _num1, int _num2) { num1 = _num1; num2 = _num2; } void sumNum() { cout << num1 + num2 << endl; } void divisionNum() { if (num2 == 0) { throw "PPP"; } cout << num1 / num2; } ~P() {} }; int main() { setlocale(LC_ALL, "rus"); P obj2(10, 0); try { obj2.divisionNum(); } catch (char *s) { cout << s << endl; } system("pause"); } 

    Just changed string s to char * s

    • I am afraid that your decision is a crutch and very few people will need it. - Max ZS

    Just changed string s to char * s

    I am afraid that your decision is a crutch and very few people will need it. - Max ZS Mar 11 '16 at 19:20

    I'm afraid you don't know the basics in which a string like "blablabla" has type char *, and the exception quite correctly catches it. Want to catch a string - write:

     string s = "blablabla"; throw s; 

    or something like

     throw string("blablabla");