Задайте себе этот вопрос:
«Что такое обещание моей функции, и, следовательно, ожидание своего клиента
Если функция обещает вернуть объект, бросить исключение, если он не может исключением является неспособность держать обещание
например:..
T make_t(Arg arg); // promises to make a T, should throw if it can't
Если функция обещает, что может возвращать объект, а затем выразить, что в интерфейсе:
boost::optional<T> maybe_make_t(Arg arg);
В этом случае, мы не ожидали бы исключение, если объект не был сделан, просто пустой optional<T>
. Поскольку мы вернули необязательный, вызывающий должен проверить его, прежде чем использовать значение (или получить исключение). Теперь он защищен от своих логических ошибок.
Если вы можете избежать этого, старайтесь избегать обратных указателей. Они создают логические головные боли для ваших абонентов.
Возможно (по какой-либо причине) вы хотите избежать исключений, но все же спокойно сообщать о неудачах сдержать обещание?
Вот один из способов:
boost::variant<T, std::string> make_t_or_reason_why_not(Arg arg);
Теперь вы заставляете вызывающий использовать статическую посетителя обрабатывать свой результат (это хорошо, что заставляет его, чтобы охватить все пути коды!).
обещание, что вы будет возвращение что-то, и что он будет либо быть T
или string
объяснить, почему T
не было сделано.
Назад в тот день, когда возвращался NULL, потому что он избегает необходимости копировать большой объект. Однако в наши дни с C++ 11 и RVO больше нечего делать, так что я бы сказал, что возвращает пустой экземпляр/исключение. Кроме того, используемые голые «новые» обычно представляют собой плохую идею, особенно если у вас есть доступ к умным указателям. –