13.4.4 String outs

When a String_var is passed as an out parameter, any previous value it refers to must be implicitly freed. To give C++ mapping implementations enough hooks to meet this requirement, the string type also results in the generation of a String_out type in the CORBA namespace that is used solely as the string out parameter type. The general form for the String_out type is as follows:

// C++
class String_out
{
  public:
    String_out(char*& p) : ptr_(p) { ptr_ = 0; }
    String_out(String_var& p) : ptr_(p.ptr_) {
       string_free(ptr_); ptr_ = 0;
    }
    String_out(String_out& s) : ptr_(s.ptr_) {}
    String_out& operator=(String_out& s) {
       ptr_ = s.ptr_; return *this;
   }
   String_out& operator=(char* p) {
      ptr_ = p; return *this;
   }
   String_out& operator=(const char* p) {
      ptr_ = string_dup(p); return *this;
   }
   operator char*&() { return ptr_; }
   char*& ptr() { return ptr_; }
private:
   char*& ptr_;

   // assignment from String_var disallowed
   void operator=(const String_var&);
};

The first constructor binds the reference data member with the char* &argument. The second constructor binds the reference data member with the char* held by the String_var argument, and then calls string_free() on the string. The third constructor, the copy constructor, binds the reference data member to the same char* bound to the data member of its argument.

Assignment from another String_out copies the char* referenced by the argument String_out to the char* referenced by the data member. The overloaded assignment operator for char* simply assigns the char* argument to the data member. The overloaded assignment operator for constchar* duplicates the argument and assigns the result to the data member. The assignment does not cause any previously held string to be freed; in this regard, the String_out type behaves exactly as a char*. The char* &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.

Assignment from String_var to a String_out is disallowed because of the memory management ambiguities involved. Specifically, it is not possible to determine whether the string owned by the String_var must be taken over by the String_out without copying, or if it must be copied. Disallowing assignment from String_var forces the application developer to make the choice explicitly, as follows:

// C++
void
A::op(String_out arg)
{
    String_var s = string_dup("some string");
    ...
    out = s;                // disallowed; either
    out = string_dup(s);    // 1: copy, or
    out = s._retn();        // 2: adopt
}

On the line marked with the comment “1,” the caller is explicitly copying the string held by the String_var and assigning the result to the out argument. Alternatively, the caller could use the technique shown on the line marked with the comment “2” to force the String_var to give up its ownership of the string it holds so that it may be returned in the out argument without incurring memory management errors.