Matteo Cultrera
Matteo Cultrera

Reputation: 60

Best way to write a constructor that could have invalid parameters

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

Answers (1)

lubgr
lubgr

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

Related Questions