不应抛出非异常类型的对象
7.5 ID_throwNonExceptionType
不应将整数、字符串等非异常类的对象当作异常抛出,否则意味着异常相关的设计是不健全的。
完善的异常类型应满足如下需求:
- 可以将异常合理分类
- 提供对异常情况的准确描述
- 使异常便于处理和调试
非异常类型难以满足这种需求。
示例:
void foo() {
if (cond) {
throw 1; // Non-compliant
}
throw "message"; // Non-compliant
}
整数或字符串无法区分异常的种类,如果不同的功能模块均将简单变量作为异常,很容易产生冲突。
如果条件允许,应选择适当的标准异常类作为基类,并实现相关接口:
class MyError: public std::logic_error {
public:
MyError(const char* msg): std::logic_error(msg) {}
};
void bar() {
throw MyError("message"); // Compliant
}
这样可使异常类形成继承体系,便于分类管理。
另外,要注意 throw、try、catch 等关键字应专注于异常处理,不应使用这些关键字控制程序的业务流程,业务代码与异常处理代码应有明显区别,否则会使代码含混不明,效率也会降低,如:
void bar(const vector<string>& v, const string& s) {
auto b = v.begin();
auto e = v.end();
for (auto i = b; i != e; ++i) {
if (*i == s) {
throw i - b; // Non-compliant
}
}
throw -1; // Non-compliant
}
例中 bar 函数抛出字符串 s 在容器 v 中的位置,用异常机制实现与异常无关的功能,是不符合要求的。
配置
mustInheritStdException: 是否要求异常类必须派生自 std::exception