13.4 outクラスの使い方

TYPE_varoutパラメータとして渡される場合、それが参照していた以前の値はすべて暗黙的に削除される必要があります。この要件を満たすのに十分なフックをORBに提供するために、各T_var型には対応するTYPE_out型があります。この型は、outパラメータ型としてのみ使用します。

ノート:

プログラマは、_outクラスを直接インスタンス化できません。そのため、_outクラスは関数のシグネチャでのみ指定してください。

可変長型のTYPE_out型の全般的な形式は、次のとおりです:

// 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&):
};

最初のコンストラクタは、リファレンス・データ・メンバーをT*&引数にバインドし、ポインタをゼロ(0)ポインタ値に設定します。2番目のコンストラクタは、リファレンス・データ・メンバーをTYPE_var引数が保持しているポインタにバインドし、ポインタに対してdeleteを呼び出します(その際に、型がString_outの場合はstring_free()を、配列型TYPE TYPE_varの場合はTYPE_free()を呼び出します)。3番目のコンストラクタはコピー・コンストラクタで、コンストラクタ引数のデータ・メンバーによって参照される同じポインタにリファレンス・データ・メンバーをバインドします。

他のTYPE_outからの代入により、TYPE_out引数によって参照されるTYPE*がデータ・メンバーにコピーされます。TYPE*のオーバーロードの代入演算子は、単にポインタ引数をデータ・メンバーに代入します。代入を行っても、以前に保持されていたポインタは削除されません。この点では、TYPE_out型の動作は、TYPE*とまったく同じです。 TYPE*&変換演算子は、データ・メンバーを返します。ptr()メンバー関数もデータ・メンバーを返しますが、暗黙的な変換の実行を避ける場合に使用できます。オーバーロードの矢印演算子(operator->())を使用すると、TYPE*データ・メンバーが指すデータ構造体のメンバーにアクセスできます。準拠アプリケーションでは、有効な非NULL TYPE *TYPE_outが初期化済でないかぎり、オーバーロードのoperator->()を呼び出すことはできません。

対応するTYPE_var型のインスタンスから、TYPE_outに代入することはできません。これは、アプリケーション開発者がコピーを行うかどうか、またはTYPE_varTYPE_outに代入できるよう、それが管理するポインタの所有権を返す必要があるかどうかを判定する方法がないためです。TYPE_varTYPE_outにコピーするには、アプリケーションで次のようにnewを使用する必要があります:

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

通常、tに対して呼び出されるin()関数は、const TYPE&を返し、新しく割り当てられたTインスタンスのコピー・コンストラクタを呼び出すことができるようにします。

また、 TYPE_varが管理するポインタの所有権を放棄して、T_outパラメータで返せるようにするには、アプリケーションで、次のようにTYPE_var::_retn()関数を使用する必要があります:

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

ノート:

TYPE_out型は、アプリケーションで作成または破棄される汎用目的のデータ型としては機能しません。この型は必要なメモリー管理を適切に行う目的で、操作のシグネチャの内部でのみ使用する型です。