Hos*_*815 15 c++ api error-handling exception
我正在Windows上用VS 2010编写C++ API,它从DLL导出几个类.我们计划稍后支持其他平台(MacOS,Linux).
我目前正在考虑如何设计错误处理.我不想使用异常,因为跨越DLL边界的问题(至少在Windows中).
到目前为止,我想出了以下三种设计.
设计1:
对于每一个方法的返回值将表明,如果操作成功或通过返回要么没有true/false或pointer/nullptr分别.然后,客户端可以调用GetLastError()以检索错误代码(枚举),该错误代码详细说明了上次失败.
typedef std::shared_ptr<Object> ObjectPtr;
class APIClass
{
bool SetSomething(int i);
bool IsSomethingSet();
bool DoSomething();
ObjectPtr GetSomething();
ErrorCode GetLastError();
}
Run Code Online (Sandbox Code Playgroud)
设计2:
每种方法都返回一个错误代码.[out]参数应该通过值或(const)引用作为指针和[in]参数传递.
typedef std::shared_ptr<Object> ObjectPtr;
class APIClass
{
ErrorCode SetSomething(int i);
ErrorCode IsSomethingSet(bool* outAsk);
ErrorCode DoSomething();
ErrorCode GetSomething(ObjectPtr* outObj);
}
Run Code Online (Sandbox Code Playgroud)
设计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);
}
Run Code Online (Sandbox Code Playgroud)
我想保持设计简单,一致和干净.您更喜欢哪种设计作为客户?对于更好的设计,您有其他建议吗?你能说出为什么一个设计更好或者它只是一个品味问题的原因吗?
注意: 这里有一个类似的问题:C++ API设计和错误处理.但我不想在接受的答案中使用解决方案,或者使用boost :: tuple之类的东西作为返回值.
好的,所以无异常约束会导致问题......我不会质疑.
总而言之,哪个最好取决于您的API的具体情况:您倾向于返回的值是否具有备用的标记值,是否要强制/鼓励开发人员更明确地准备和处理错误代码或使其更具可选性,隐含和/或简洁.您可能还会考虑您已经使用的其他库的实践,特别是如果对于调用者来说,给定函数来自哪个库并不明显.因为没有一个单一的最佳通用答案,这个问题在C世界中存活了这么多年(并且C++有例外).
一些讨论点......
Sentinel值(根据设计1中的指针)在调用者预期时非常有效(例如程序员倾向于问自己"我能得到一个空指针吗?它意味着什么?"),直观,一致,以及最好是如果它们可以隐含地转换为布尔值,那么它们就会成功!这看起来要好得多,尽管很明显许多操作系统和标准C库函数返回-1表示失败,因为0在有意义的结果集中通常是有效的.
您隐含理解的另一个考虑因素:依靠函数调用之外的状态引入线程和异步(信号处理)安全问题.您可以记录开发人员不应该从线程/异步代码限制对象的使用,或者为错误代码提供特定于线程的存储,但这是一个额外的痛苦维度.返回或传入ErrorCode对象可以避免这个问题.传入ErrorCode对象对调用者来说是一个恒定的小负担,但确实鼓励他们明确地考虑错误处理.
| 归档时间: |
|
| 查看次数: |
2543 次 |
| 最近记录: |