处理错误
描述 C++ API 中的错误处理。
在 Concert Technology 中,对两类错误进行了区分:
-
编程错误,例如:
-
访问空句柄对象;
-
混合来自不同环境的建模对象;
-
访问数组大小以外的 Concert Technology 数组元素;以及
-
将大小不兼容的数组传递给函数。
此类错误通常是因为程序员疏忽所致。 确定并修正这些错误通常不会有损坏应用程序的危险。 在生产应用程序中,不必处理这些类型的错误。
在 Concert Technology 中,此类错误条件是使用断言语句加以处理。 如果是在未指定
-DNDEBUG
的情况下进行编译,那么将执行错误检查,代码将中止,并发出错误消息以指示哪项断言失败。 然后,应该在指定-DNDEBUG
编译器选项的情况下编译生产应用程序,这将移除所有检查。 换言之,检查断言不会耗用任何 CPU 周期。
-
-
运行时错误,例如内存耗尽。
正确的程序假定可能会发生此类故障,因此必须加以处理,即使在生产应用程序中也是如此。 在 Concert Technology 中,如果发生此类错误情况,那么将抛出异常。
Concert Technology 类(包括 IloCplex
)所抛出的所有异常都是从
IloException
派生。 算法类(例如 IloCplex
)所抛出的异常是从其子级类
IloAlgorithm::Exception
派生。
CPLEX
所抛出的最常见异常是从 IloCplex_Exception(IloAlgorithm::Exception
的子级类)派生的。
异常类 IloCplex::Exception
的对象对应于 CPLEX Callable Library
所生成的错误码。
可通过调用以下方法来查询所捕获到的异常中的错误码:
IloInt getStatus () const;
可通过调用以下方法来查询错误消息:
const char* IloException::getMessage() const;
此方法是从基类 IloException
继承的虚方法。 如果您只希望访问消息以便列显到通道或输出流,那么更方便的做法是使用
Concert Technology 为 IloException
提供的重载输出运算符
(operator<<
)。
除了与 C Callable Library 中的错误码相对应的异常以外,cplex
对象还可抛出仅与 IloCplex
相关的异常。
例如,如果抽取的模型包含多个目标函数,那么将抛出 MultipleObjException 异常。这样的附加异常类是从类 IloCplex_Exception 派生的;可通过调用 getStatus
方法时返回的负状态码来识别对象。
与大多数其他 Concert Technology 类不同,异常类不是句柄类。 因此,如果通过值而非引用来捕获异常(即,使用 catch(IloException& e) {...}
),那么该异常的正确类型将丢失。
这就是通过引用来捕获 IloException
是一种好想法的其中一个原因,所有示例都演示了这种做法。
例如,请参阅 ilodiet.cpp
。 某些派生异常可能包含通过值捕获时将会丢失的信息。
因此,与输出通过值捕获到的异常相比,输出通过引用所捕获到的同一异常可获得更加准确的消息。
通过引用来捕获异常还有一种原因。
某些异常包含数组,以传达无法调用函数的原因。 如果通过值调用该异常时丢失此信息,就无法针对此类数组调用 end
方法,它们的内存将泄露(直至调用 env.end
为止)。 通过引用捕获异常之后,调用该异常的 end
方法将释放所抛出实际异常的数组(或表达式)所可能使用的所有内存。
总之,捕获异常的首选方法如下:
catch (IloException& e) {
...
e.end();
}
其中,IloException
可以替换为期望的 Concert Technology 异常类。