| 概述 | 组 | 树 | 图形 | 不推荐 | 索引 | 概念 |
作为建模层,Concert 允许通过 "IloExtractable::end和 "IloExtractableArray::endElements方法创建和销毁可提取物。 这些方法的目的是回收与已删除对象相关的内存,同时保持尽可能安全的 Concert 环境。 在这种情况下,安全 Concert 环境的定义是:没有对象指向被删除的对象;指向被删除对象的指针在 C++ 中被称为悬空指针。
要确保删除操作的安全性,有两种范例。 第一种是线性模式,来自数学编程;在 Concert 应用程序中,线性模式只适用于可提取对象和线性编程中使用的其他对象。 第二种安全通用模式更为严格,适用于所有 Concert 可提取对象。
您可以通过调用 "IloEnv::setDeleter(IloDeleterMode mode)访问这两种范式,其中模式可以是 "IloLinearDeleterMode或 "IloSafeDeleterMode。
线性模式
要使用线性模式,您必须
IloEnv::setDeleter(IloLinearDeleterMode),或IloEnv::setDeleter,因为线性是默认模式。在线性模式下,执行以下行为:
IloConversion实例中删除。示例
本例测试以线性模式删除变量 "x。
voidTestLinearDeleter() {
IloEnv env;
env.out() <<"TestLinearDeleter"<< endl;
try {
IloModel model(env);
IloNumVarx(env,0,10,"x");
IloNumVary(env,0,10,"y");
IloConstraintcon = (x + y <= 0);
IloConstraint con2= y >= 6;
IloNumVarArrayar(env, 2, x, y);
IloSOS1sos(env,ar,"sos");
model.add(con);
model.add(con2);
model.add(sos);
env.out() << "删除前" << endl;
env.out() << model << endl;
x.end();
con2.end();
env.out() << "删除后" << endl;
env.out() << model << endl;
} catch (IloException& e) {
cout << "Error : " << e << endl;
}
env.end();
}
示例的输出结果如下
TestLinearDeleter
删除前
IloModel model0 = {
IloRange rng3(1 * x + 1 * y ) <= 0
IloRange rng46<=( 1 * y )
IloSOS1I(sos)
_varArray[x(F)[0...10], y(F)[0...10]]
_valArray []
}
删除后
IloModel model0 = {
IloRange rng3(1 * y ) <= 0
IloSOS1I(sos)
_varArray[y(F)[0...10]]
_valArray []
}安全通用模式
要使用安全通用模式,必须
IloEnv::setDeleter(IloSafeDeleterMode),以及#include <ilconcert/ilodeleter.h>。在这种模式下,环境会在所有可提取对象之间建立依赖关系图。 该图包含创建的所有可提取对象
IloEnv::setDeleter(IloSafeDeleterMode)和IloEnv::unsetDeleter。不受此依赖关系图管理的对象在此称为 "不可删除 "对象。 试图删除不可删除对象时会出现异常。
建议在创建环境后再创建此图,并且不要使用 "IloEnv::unsetDeleter,因为创建不完整的依赖关系图非常容易出错,只有高级用户才能尝试。 这种不完整图形的一个明显例子是,将一个模型分离为不可删除的基本模型和该基本模型的可删除扩展模型。
只有当没有其他可提取对象使用可提取的 "xi时,在可提取的 "xi上调用 "IloExtractable::end才会成功。 如果不是这种情况,调用 "IloExtractable::end时将抛出异常 "IloDeleter::RequiresAnotherDeletionException,表明哪个可提取对象使用了您要删除的可提取对象。
示例
本例显示了删除一个可提取对象的尝试,该对象被另一个可提取对象使用。
voidTestSafeDeleter() {
IloEnv env;
env.out() <<"TestSafeDeleter"<< endl;
env.setDeleter(IloSafeDeleterMode);
try {
IloModel model(env);
IloNumVarx(env,0,10);
IloNumVary(env,0,10);
IloConstraintcon = (x + y <= 0);
try {
x.end();
} catchIloDeleter::RequiresAnotherDeletionException&e) {
cout << "Caught " << e << endl;
e.getUsers()[0].end();
e.end();
}
x.end();
} catch (IloException& e) {
cout << "Error : " << e << endl;
}
env.unsetDeleter();
env.end();
}
示例的输出结果如下
TestSafeDeleter 捕获 您不能在'IloRange'rng3(1 * 'x1+ 1 * 'x2之前结束'x1(F' )[0...10] ) <= 0
要解决这种情况,应该使用 "IloExtractableArray::endElements方法。 使用这种方法,数组中所有可提取对象都会被逐个删除。 因此,如果一个可提取对象被另一个可提取对象使用,而这个另一个可提取对象在第一个可提取对象之前被删除,系统不会抱怨,也不会抛出异常。
示例
本例说明了 "endElements方法的使用方法
voidTestSafeDeleterWithArray() {
IloEnv env;
env.out() <<"TestSafeDeleterWithArray"<< endl;
env.setDeleter(IloSafeDeleterMode);
try {
IloModel model(env);
IloNumVarx(env,0,10);
IloNumVary(env,0,10);
IloConstraintcon = (x + y <= 0);
IloExtractableArrayar(env, 2, con, x);
ar.endElements();
} catch (IloException& e) {
cout << "Error : " << e << endl;
}
env.unsetDeleter();
env.end();
}
该示例不会产生异常。
con必须出现在变量 "x之前,因为它将在变量 "x之前被删除。