The IDL compiler generates _var
types for the following:
The compiler generates _var
types for fixed length structured types as well as for variable length structured types for consistency. Both use the same syntax.
You can consider a _var
type as an abstract pointer. It assumes ownership of the data that it points to. For example:
//IDL interface A { void op( ); }; interface B : A { . . . };
This example maps to the following C++ code:
//C++ { //aPtr refers to an object A_ptr aPtr = ... A_var aVar = aPtr; // aVar has ownership of aPtr //The object reference is not duplicated. a_Var ->op( ); . . . } // aVar is released and ref count decremented.
In the example, the member is accessed indirectly using an arrow ->
rather than a dot.
The format of the T_var
class in C++ is as follows:
//C++ class T-var { public; T_var( ); T_var(*T p); T_var(const T_var& s); T_var& operator=(T* p); T_var& operator=(const T_var& s); ~T_var( ); T* operator->( ); //Conversion operators to support //parameter passing. };
The default constructor creates a T_var
that contains a null pointer to the data or a nil object reference. A T_var
initialized with the default destructor.
The second constructor creates a T_var
that will free the storage that its (non-null) parameter points to when it is destroyed.
The copy constructor performs a deep copy of any data that the T_var
constructor parameter points to. The copy is freed if the T_var
is destroyed or if a new value is assigned to T_var
.
The destructor uses delete to deallocate any data that the T_var:strings
points to. The string_free( )
and S_free( )
functions can be used to deallocate array types. When freed, the object references are released.
The T*
assignment operator is used to deallocate data pointed to by the T_var
than assumes ownership of the T*
(or Y_ptr
) parameter.
The normal assignment operator deep copies data pointed to by the T_var
assignment parameter. This copy is destroyed when the T_var
is destroyed or if a new value is assigned to T_var
.
When a T_var
is passed as an out
parameter, previous values assigned to it are deleted. Each T_var
type has a corresponding T_out
type used as an out parameter type.
The general format of the T_out
types is as follows:
// C++ class T_out { public: T_out(T* p) : ptr_(p) { ptr_ = 0; } T_out(T_var& p) : ptr_(p.ptr_) { delete ptr_; ptr_ = 0; } T_out(T_out& p) : ptr_(p.ptr_) {} T_out& operator=(T_out& p) { ptr_ = p.ptr_; return *this; } T_out& operator=(T* p) {ptr_ = p; return *this;} operator T*&( ) { return_ptr_; } T*& ptr( ) { return ptr_; } private: T*& ptr_; //assignment from T_var not allowed void operator=(const T_var&): };
The first constructor binds the reference data member with the T*&
argument and sets the pointer to null. The second constructor binds the reference data member with the pointer held by the T_var
argument, then calls delete for the pointer, string_free( )
for String_out
, or T_free( )
in the case of an array of type T
.
The third constructor is a copy constructor that binds the reference data member to the pointer referenced by the data member of the constructor argument.
In addition to the regular operations defined for T_var
and T_out
, T_var
and T_out
also support an overloaded operator. The overloaded operator allows access to members of the data structure.
In the following code, the Array_var
class owns and manages an array. The symbol [&] denotes an optional ampersand which is present for arrays with variable-length elements.
class Array_var { public: Array_var( ) : ip_var(NULL) {} Array_var(Array_slice_ptr ptr) : ip_var(ptr) {} Array_var(const Array_var &var){ *this = var; } ~Array_var( ) { Array_free(ip_var); } Array_var &operator =(Array_slice_ptr ptr) { Array_free(ip_var); ip_var = ptr; return *this; } Array_var &operator =(const Array_var &var); { if (var.ip_var != NULL) { ip_var = Array_dup(var.ip_var); } else { ip_var = NULL; } return *this; } Array_slice &operator [](CORBA::ULong index) { if (index >= N1) NSDTHROW(new CORBA::BadParam(MINOR_ARRAY_INDEX)); return ip_var[index]; } const Array_slice &operator [](CORBA::ULong index) const { if (index >= N1) NSDTHROW(new CORBA::BadParam(MINOR_ARRAY_INDEX)); return ip_var[index]; } Array_slice *in( ) const { return ip_var; } Array_slice *inout( ) { return ip_var; } Array_slice *[&]out( ) { Array_free(ip_var); ip_var = NULL; return ip_var; } Array_slice *_retn( ) { Array_slice *lp_temp = ip_var; ip_var = 0; return lp_temp; } friend NSDOM_Encap &operator <<(NSDOM_Encap &prEncap, const Array_var &array_var); friend NSDOM_Encap &operator >>(NSDOM_Encap &prEncap, Array_var &array_var); private: Array_slice_ptr ip_var; }; |