Я пишу C ++ API для Windows с VS 2010, который экспортирует несколько классов из DLL. Мы планируем поддерживать другие платформы позже (MacOS, Linux).
В настоящее время я думаю, как спроектировать обработку ошибок. Я не хочу использовать исключения из-за проблемы через границы DLL (по крайней мере, в Windows).
До сих пор я придумал следующие три дизайна.
Дизайн 1:
Для каждого метода возвращаемое значение будет указывать, была ли операция успешной или неудачной, возвращая либо true/false
, либо pointer/nullptr
соответственно. Затем клиент может вызвать GetLastError()
для получения кода ошибки (enum), который подробно описывает последний сбой.
typedef std::shared_ptr<Object> ObjectPtr;
class APIClass
{
bool SetSomething(int i);
bool IsSomethingSet();
bool DoSomething();
ObjectPtr GetSomething();
ErrorCode GetLastError();
}
Дизайн 2:
Каждый метод возвращает код ошибки. Параметры [out] должны передаваться как указатели, а параметры [in] - по значению или по (const) ссылке.
typedef std::shared_ptr<Object> ObjectPtr;
class APIClass
{
ErrorCode SetSomething(int i);
ErrorCode IsSomethingSet(bool* outAsk);
ErrorCode DoSomething();
ErrorCode GetSomething(ObjectPtr* outObj);
}
Дизайн 3:
Как и дизайн 1, но вы можете передать необязательный код ошибки в качестве параметра [out] для каждой функции.
typedef std::shared_ptr<Object> ObjectPtr;
class APIClass
{
bool SetSomething(int i, ErrorCode* err = nullptr);
bool IsSomethingSet(ErrorCode* err = nullptr);
bool DoSomething(ErrorCode* err = nullptr);
ObjectPtr GetSomething(ErrorCode* err = nullptr);
}
Я хочу, чтобы дизайн был простым, последовательным и чистым. Какой дизайн вы бы предпочли в качестве клиента? У вас есть другие предложения по улучшению дизайна? Можете ли вы объяснить, почему один дизайн лучше или это просто вопрос вкуса?
Примечание:
Здесь есть похожий вопрос: Разработка C ++ API и обработка ошибок . Но я не хочу использовать решение в принятом ответе или использовать что-то вроде boost :: tuple в качестве возвращаемого значения.