Бросить конструктор при неверном вводе - это хорошо, и даже рекомендуется согласно основным рекомендациям .
Именованные конструкторы (то есть статические функции-члены) являются одинаково допустимым подходом, например, они могут возвращатьstd::optional<YourType>
(требуется C ++ 17).Это делает очевидным, что реализация может потерпеть неудачу, и обходит недостатки исключений.Вот небольшой пример.
#include <optional>
class Example {
public:
static std::optional<Example> validateAndCreate(...);
private:
/* Private ctor makes usage of the above function mandatory. */
Example(...);
};
И реализация метода создания может быть
std::optional<Example> validateAndCreate(...)
{
/* Use e.g. some utility function for validation: */
if (isInputValid(/* Pass parameter. */))
return Example(/* Pass parameter. */);
else
return std::nullopt;
}
, где код клиента затем конструирует объекты, подобные этому:
if (const auto instance = Example::validateAndCreate())
/* Do stuff with the instance. */
;
else
std::cerr << "What now?\n";
Я полагаю, что этот подход более самодокументирован (тот факт, что ctor может генерировать код, должен быть где-то задокументирован), но также более многословен.