Should I make an exception?

I am a C # programmer, but now I want to get more in C ++.
I know the basics of C ++, but I don't know how to handle errors.

For example: I am writing a library. I am creating a constructor that requests an integer as an argument.
If this integer is greater than 50, this is an error. In C #, I would throw an ArgumentOutOfRange exception, but what should I do in C ++?

+6
source share
4 answers

In C #, I would throw an ArgumentOutOfRange exception, but what should I do in C ++?

You should first consider whether this should be a prerequisite for your function, leaving it to the test to determine if the value is in the range of the caller.

If you decide this option, then calling the function with an out-of-range value will be undefined, and inside the function you can just have a debug statement to help you identify possible abuses - without having to throw any exception.

If you decide that the function should have a broad contract, on the other hand, and respond in a clearly defined way, throwing an exception if the argument is outside the valid range, you can throw a std::out_of_range exception.

For example: I write libary [...]

If you are writing a library, which means that you do not know the exact requirements of your customers in terms of performance and reliability, you can consider providing two such functions: one with a wide contract that generates exceptions, and one with a narrow contract that assumes that the client provides a meaningful contribution.

Thus, the user of your library could decide, based on his use cases, whether it is correct to pay the overhead of checking the correctness of input with each function call.

This is, for example, the strategy adopted by the standard C ++ library for std::vector , which provides non-casting of operator[] with a narrow contract for accessing collection items based on the index (this function has undefined behavior if the index is out of bounds), and the member function at() , which performs an index check and throws an exception if the index is out of bounds.

+21
source

This depends on whether an integer greater than 50 can be passed to the constructor as part of the normal program flow or an exceptional condition. But, as a rule, the only way to destroy an object is to throw an exception.

Your user code might look like this:

 int n = parse_user_input() if (n < 50) { Foo x(n); x.do_cool_stuff(); } else { // report user error } 

That is, you are not actually using exceptions for the normal control flow. With this type of code, it would be great if Foo::Foo(int) threw an exception if the argument was out of range.

You can find useful standard exception classes in <stdexcept> .

+4
source

Same as in C #: throw an exception. This is the only way to prevent the creation of an object.

std::invalid_argument - good standard choice as to what to give up.

+3
source

From the C ++ FAQ: [17.8] How can I handle a constructor that fails?

Excerpts:

Throw an exception.

Constructors do not have a return type, so return codes cannot be used. Thus, the best way to signal constructor failure is to throw an exception. If you don’t have the ability to use exceptions, the “least bad” job is to put the object in the “zombie” by setting the internal status bit so that the object acts as if it were dead, although it is technically still alive.

So casting std::invalid_argument or std::out_of_range would be perfectly acceptable for your situation. You can also throw a custom exception if this is useful in your situation. In the C ++ FAQ, see: [17.12] What should I do?

0
source

Source: https://habr.com/ru/post/945774/


All Articles