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;
};
|