I want to throw an exception in my constructor so that I don’t have to deal with zombie objects. However I also want to provide a validation method upfront so that people can avoid “dealing with exceptions” where there is no cause to. In a GUI it’s not exceptional to expect invalid data. However I also want to avoid code duplication and overhead. Is GCC / Microsoft Visual C++ compiler smart enough to remove this inefficiency of validating an input twice and if not, is there a subtle change that could please?
An example code block illustrating my point is below:
#include <string>
#include <exception>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
using std::exception;
// a validation function
bool InputIsValid(const string& input) {
return (input == "hello");
}
// a class that uses the validation code in a constructor
class MyObject {
public:
MyObject(string input) {
if (!InputIsValid(input)) //since all instances of input
throw exception(); //has already been validated
//does this code incur an overhead
//or get optimised out?
cout << input << endl;
};
};
int main() {
const string valid = "hello";
if (InputIsValid(valid)) {
MyObject obj_one(valid);
MyObject obj_two(valid);
}
return 0;
}
I anticipate this may not be possibly if the object file for the class is generated alone as the object file has no way to ensure people will validate before calling the constructor, but when an application is compiled and linked together in a single application, is it possible please?
Yes, if the data is already validated, then you would incur the cost of validating it again
You could encapsulate your input in an object, and that object would remember the result of validation.
The constructor to
InputObjectcalls the validator function for you, and stores the result of validation in a flag. ThenMyObjectjust checks the flag, and doesn’t have to do the validation again.As suggested by DeadMG, stronger type checking can be achieved by insisting that
MyObjectonly accept validated input. Then, it would not need tothrowin the constructor at all. Such a scheme could be accomplished by makingNonValidatedInputandValidatedInputtwo different types.NonValidatedInputaccepts non-validated input, and performs the validation, and can be converted to aValidatedInputobject if the validation succeeds. If the validation fails,NonValidatedInputthrows an exception. Thus,MyObjecthas no need to check for validation at all, because it’s constructor only acceptsValidatedInput.The type safety here is quite strong, because only
NonValidatedInputcan create aValidatedInput, and only if the validation succeeded.