Skip to main content
FRAMES NO FRAMES

Creation of extractable objects
PREVIOUS NEXT

For most Concert applications, you can simply create the extractable objects that you need to build your model, then let their destructors manage the subsequent deletions. However, when memory use is critical to your application, you may need to take control of the deletion of extractable objects. In such cases, you will need a deeper understanding of how IBM® ILOG® Concert Technology creates and maintains extractable objects. The following guidelines, along with the concept Deletion of Extractable Objects, should help.

1. An expression (that is, an instance of the class IloExpr or its superclasses IloNumExpr and IloNumExprArg) is passed by value to an extractable object (an instance of the class IloExtractable). Therefore, you can delete the original expression after passing it by value without affecting the extractable object that received it.

All copies by value are deep copies, not shallow copies.

More generally, if you have multiple handles passed to Concert objects pointing to an instance of IloExpr, and you call a method that modifies one of those handles, Concert Technology performs a lazy copy. In other words, it first copies the implementation object for the handle you are modifying and then makes the modification. The other handles pointing to the original implementation object remain unchanged, and your modification has no impact on them.

Lazy copying does not apply to other Concert Technology objects. In general, it is recommended that you avoid using multiple handles to the same object if you do not feel comfortable with lazy copying.

2. A variable (that is, an instance of IloNumVar, IloIntVar, or IloBoolVar) is passed by reference to an extractable object. Therefore, when your Concert application is in linear deleter mode, deleting a variable will remove it from any extractables that received it.

3. An extractable object is passed by reference to a logical constraint (such as IloIfThen) or to a nonlinear expression (such as IloMax). Therefore, you should not delete the original expression after passing it to such functions unless you have finished with the associated model.

Here are some examples to consider in light of these guidelines. The first example illustrates guidelines 2 and 3.

      IloEnv env;
      IloNumVar x(env, 0, IloInfinity, "X");
      IloNumVar y(env, 0, IloInfinity, "Y");
      IloNumVar z(env, 0, IloInfinity, "Z");

      IloExpr e = x + y;

      IloConstraint c1 = (e <= z);
      IloConstraint c2 = (e >= z);
      IloConstraint c3 = IloIfThen(env, c1, c2);
      e.end();           // OK; c1 and c2 use copies of e;
      c1.end();          // BAD IDEA; c3 still references c1
      IloModel m(env);
      m.add (c3);        // c3 is not correctly represented in m.

In that example, since c1 is passed by reference, the call to c1.end raises errors. In contrast, the call to e.end causes no harm because e is passed by value.

The following example illustrates guidelines 1 and 2.

      IloEnv env;
      IloModel model(env);
      IloNumVar y(env, 0, 10, "y");
#ifdef WILLDELETE
      IloNumVar y2 = y;     // second handle pointing to implementation of y
#else
      IloExpr y2 = y;       // first handle pointing to expression 1*y
#endif
      IloConstraint cst = y2 <= 6;
      model.add(cst);
      y2.end();

When y2 is an instance of the class IloNumVar, the call to y2.and will remove y2 from the constraint cst, according to guideline 2.

When y2 is an expression, it will be passed by value to the constraint cst, according to guideline 1. Hence, the call to y2.end will leave cst untouched.

While a thorough understanding of these conventions provides you with complete control over management of the extractable objects in your application, in general, you should simply avoid creating extra handles to extractable objects that can result in unexpected behavior.

In light of that observation, the previous example can be simplified to the following lines:

    IloEnv env;
    IloModel model(env);
    IloNumVar y(env, 0, 10, "y");
    IloConstraint cst = y <= 6;
    model.add(cst);
PREVIOUS NEXT