Reputation: 60
I have a question about writing readable and efficient code in C++.
I’m creating a class for tcp connections with a constructor that takes as input the IP of the server and the port. I would like to avoid the creation of the object if for example the IP is wrong.
My question is:
Is it better to throw an exception in case of a failure or create a wrapper class with a Boolean to check if the internal object was created correctly and avoid calling any functions in case of failure?
Upvotes: 0
Views: 463
Reputation: 38277
Throwing in a constructor upon invalid input is fine and even recommend by the core guidelines.
Named constructors (i.e. static member functions) are an equally valid approach, they could e.g. return a std::optional<YourType>
(C++17 is required, then). This makes it obvious that the instantiation could fail and circumvents the drawbacks of exceptions. Here's a small example.
#include <optional>
class Example {
public:
static std::optional<Example> validateAndCreate(...);
private:
/* Private ctor makes usage of the above function mandatory. */
Example(...);
};
And an implementation of the creation method could be
std::optional<Example> validateAndCreate(...)
{
/* Use e.g. some utility function for validation: */
if (isInputValid(/* Pass parameter. */))
return Example(/* Pass parameter. */);
else
return std::nullopt;
}
where client code then constructors objects like this:
if (const auto instance = Example::validateAndCreate())
/* Do stuff with the instance. */
;
else
std::cerr << "What now?\n";
I guess this approach is more self-documenting (the fact that a ctor might throw should be documented somewhere), but also more verbose.
Upvotes: 3