Using exceptions to abort series of user inputs - Good? Bad?
Consider a scenario where a console application asks for a series of inputs, one after the other. Each input is validated before proceeding to the next. Now if an input made by the user is invalid, an error message is shown and the user is asked if he/she wants to continue. 开发者_C百科If the user chooses no, the input process is aborted. If the user chooses yes, the user is allowed to retype the input again, and the process continues by asking for the remainder of the inputs.
If I used a read() method to handle the user inputs (which also validates the input and asks if the user wishes to continue [y/n]) that returns false if the user chooses not to continue, then I would have to check for the result of every read() call before proceeding to the next
For example:
bool valid = read("Name");
if (valid) valid = read("Age");
if (valid) valid = read("Sex");
if (valid) valid = read("DoB");
if(valid)
{
// do stuff
}
Alternatively, I can have the read() method throw an exception if the user chooses to discontinue, in which case my code would become:
try {
read("Name");
read("Age");
read("Sex");
read("DoB");
// do stuff
}catch(input_exception& e)
{}
Which of these approaches would you choose and why? (Assume that the read() method throws the exception properly after cleaning up)
NOTE: I'm not looking for arguments for and against exceptions, which is abundantly available on SO. I'm only looking for an answer to the specific question.
I, personally, would do it something like this:
bool valid = read("Name")
&& read("Age")
&& read("Sex")
&& read("DoB");
It's equivalent to the first code you posted. The && operator in C++ evaluates terms left-to-right and stops when a false outcome is encountered. This is not a compiler-specific hack, but well-defined behavior in C, C++, and many many other programming languages based on or inspired by C.
This also works for ||, but it stops when a true value is encountered rather than a false one.
I would not use exceptions in this way, as exceptions are not meant for use as a mechanism of control flow. They exist to catch, literally, exceptional circumstances, not reasonably-expected input as in the case you describe.
There are several options for coding this using a different pattern, whether using a flag, or an if-chain, or even chaining the statements together with a boolean expression as suggested in another answer (that would be my preferred method as well). All have their pros and cons, but exceptions, IMO, are definitely not the way to do this.
I think I'd use the first approach, but structure it a bit differently:
bool valid = read("Name") && read("Age") && read("Sex") && read("DoB");
At least if I understand your requirements correctly, this seems to be a simpler way to meet them than either of the above.
精彩评论