13.4 Using out Classes

When a TYPE_var is passed as an out parameter, any previous value it referred to must be implicitly deleted. To give the ORB enough hooks to meet this requirement, each T_var type has a corresponding TYPE_out type that is used solely as the out parameter type.

Note:

The _out classes are not intended to be instantiated directly by the programmer. Specify an _out class only in function signatures.

The general form for TYPE_out types for variable-length types is as follows:

// C++
class TYPE_out
{
   public:
     TYPE_out(TYPE*& p) : ptr_(p) { ptr_ = 0; }
     TYPE_out(TYPE_var& p) : ptr_(p.ptr_) { delete ptr_; ptr_ = 0;}
     TYPE_out(TYPE_out& p) : ptr_(p.ptr_) {}
     TYPE_out& operator=(TYPE_out& p) { ptr_ = p.ptr_;
                                        return *this;
     }
     Type_out& operator=(Type* p) { ptr_ = p; return *this; }

     operator Type*&() { return ptr_; }
     Type*& ptr() { return ptr_; }

     Type* operator->() { return ptr_; }
private:
     Type*& ptr_;
     // assignment from TYPE_var not allowed
     void operator=(const TYPE_var&):
};

The first constructor binds the reference data member with the T*&argument and sets the pointer to the zero (0) pointer value. The second constructor binds the reference data member with the pointer held by the TYPE_var argument, and then calls delete on the pointer (or string_free() in the case of the String_out type or TYPE_free() in the case of a TYPE_var for an array type TYPE ). The third constructor, the copy constructor, binds the reference data member to the same pointer referenced by the data member of the constructor argument.

Assignment from another TYPE_out copies the TYPE* referenced by the TYPE_out argument to the data member. The overloaded assignment operator for TYPE* simply assigns the pointer argument to the data member. Note that assignment does not cause any previously held pointer to be deleted; in this regard, the TYPE_out type behaves exactly as a TYPE*. The TYPE*&conversion operator returns the data member. The ptr() member function, which can be used to avoid having to rely on implicit conversion, also returns the data member. The overloaded arrow operator (operator->()) allows access to members of the data structure pointed to by the TYPE* data member. Compliant applications may not call the overloaded operator->() unless the TYPE_out has been initialized with a valid nonNULL TYPE * .

Assignment to a TYPE_out from instances of the corresponding TYPE_var type is disallowed because there is no way to determine whether the application developer wants a copy to be performed, or whether the TYPE_var must yield ownership of its managed pointer so it can be assigned to the TYPE_out. To perform a copy of a TYPE_var to a TYPE_out, the application must use new, as follows:

// C++
TYPE_var t = ...;
my_out = new TYPE(t.in());           // heap-allocate a copy

The in() function called on t typically returns a const TYPE&, suitable for invoking the copy constructor of the newly allocated T instance.

Alternatively, to make the TYPE_var yield ownership of its managed pointer so it can be returned in a T_out parameter, the application must use the TYPE_var::_retn() function, as follows:

// C++
TYPE_var t = ...;
my_out = t._retn();             // t yields ownership, no copy

Note:

The TYPE_out types are not intended to serve as general-purpose data types to be created and destroyed by applications; they are used only as types within operation signatures to allow necessary memory management side-effects to occur properly.