我正在编写一个具有两种不同使用模型的 C++ 类。一种是外部的,我们假设用户不希望引发任何异常。而是返回错误代码。另一种使用方式是内部的,我努力避免繁琐的错误代码检查并更喜欢处理异常。
将这两种方法结合起来的好方法是什么?
编辑:
- 两种方法都可以在同一个二进制文件中使用
- 显式优于隐式
- 避免向用户公开特殊构造。
创建该类的两个版本,一个抛出,一个返回错误代码。它们都可以从包含大量代码的公共基础派生。
我比我更喜欢 Mark Ransom 的回答,除非由于其他原因创建两个类是不可行的。
作为替代方案,您可以创建接口,以便每个函数都有一个带有默认值的最终参数,例如 int *pRet = NULL。如果 pRet == NULL 表示使用异常。如果 pRet != NULL,则调用者已传入一个指针,该指针应在函数末尾使用错误代码进行更新。
在函数内部,您需要捕获异常,然后根据 pRet 参数吞下它们或重新抛出它们。
从来没有尝试过这样的事情,但这就是我会做的。
错误类型:
extern const bool exceptionmode;
enum error_codes {no_error, whatever};
struct error_type {
error_codes id;
//maybe also a non-owning const char* message?
error_type() :id(no_error) {}
error_type(error_codes code) :id(code)
{
if (exceptionmode) throw_as_exception();
}
const char* get_as_string() {
switch(id) {
case whatever: return "out of bounds exception";
case no_error: return "no error";
default: return "unknown exception";
}
}
void throw_as_exception() {
switch(id) {
case whatever: throw std::out_of_bounds("out of bounds exception");
case no_error: break; //no error
default: throw std::exception("unknown exception");
}
}
};
类和函数:
class myclass {
public:
error_type my_member_function() {
//stuff
if (condition)
return whatever;
//more stuff
return no_error;
}
};
如果你真的很勇敢,你可以让 error_type 类断言它是否永远不会被比较、转换或检查,以确保没有人忘记检查返回值。