2016-01-02 4 views
0

Это скорее общий дизайн API, а не вопрос, связанный с C++, так или иначе, что вообще принято из функций, которые должны возвращать экземпляр класса: return NULL, если что-то пошло не так или вернули экземпляр этого класса без данных?Возврат NULL по отношению к возврату объекта obj без данных

Это мой фактический код: https://github.com/alexandernst/cpp-bitstring/blob/76030321b3a424236c3380067a0dc4f132fb8369/src/Bits.cpp#L360

+0

Назад в тот день, когда возвращался NULL, потому что он избегает необходимости копировать большой объект. Однако в наши дни с C++ 11 и RVO больше нечего делать, так что я бы сказал, что возвращает пустой экземпляр/исключение. Кроме того, используемые голые «новые» обычно представляют собой плохую идею, особенно если у вас есть доступ к умным указателям. –

ответ

1

В общем, я бы возвращать NULL или выбросить. Кодекс, который не удается, должен быть понят рано.

Альтернатива возврата «сломанного» объекта требует, чтобы каждая функция понимала, что объект сломан и имеет дело с ним.

Нулевая/бросок требует, чтобы вы обрабатывать ошибки для каждой конструкции, и в вашем лице, если он не

+0

Вы не можете «вернуть NULL», если функция возвращает экземпляр класса. –

1

Задайте себе этот вопрос:

«Что такое обещание моей функции, и, следовательно, ожидание своего клиента

Если функция обещает вернуть объект, бросить исключение, если он не может исключением является неспособность держать обещание

например:..

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 не было сделано.

Смежные вопросы