[ Eiffel Liberty | GUERL | sOOap ]
by
Alan A. Snyder
and
Brian N. Vetter
3 - 複写、複製、そして等価性 3.0 導入 3.1 オブジェクトを複写する 3.1.1 浅い複写 3.1.2 深い複写 3.2 オブジェクトを複製する - 深い複製と浅い複製 3.3 オブジェクトの等価性 - 深い等価性と浅い等価性
Eiffel は、オブジェクトを、再作成したり、複製したり、等価性のために比較したりすることを許す、いくつかの特徴を提供します。私たちは、この章で、これらの能力を検討することにします。この文書のずっと前の節で紹介した特徴の大部分は、Eiffel の言語に固有ではありませんでした。しかしながら、Eiffel は、オブジェクトを深く複写し、複製し、比較するための能力において、他の言語から Eiffel を分離します。私たちは、ここで述べることがどうして有効であるのか、ということを詳細に説明することにします。
オブジェクトを複写<copy>するということは、元になるオブジェクトの内容を、対象となるオブジェクトの中に複製<replicate>するという意味です。正確には、対象となるオブジェクトは、すでに(生成されて)存在していなければなりません。Void である対象の参照へ複写することは、例外を発生させることになります。Eiffel は、オブジェクトを複写するために二つの方法、深い複写と浅い複写、を提供します。それぞれを、順番に検討することにしましょう。
私たちは、例を用いて、浅い複写の効果を検討することにします。私たちがクラス TEDDY_BEAR の参照オブジェクトの二つの実体を持っている、と仮定してください。
![]()
次の結果は、
x.copy( y )すべてのオブジェクトへ利用可能な、浅い複写の特徴であり、次のようになるでしょう。
![]()
浅い複写は、オブジェクトの構造(他の参照)を推移<traverse>することを意図していません。この複写の効果は、参照されている直接のオブジェクトとは独立しています。浅い複写は、本質的に、属性となっているすべての特徴の項目<field>ごとの移送を実行します。上の場合、size と name です。注意していただきたいのは、多分、さまざまな操作を実行する TEDDY_BEAR で利用可能なルーチンと関数がある、ということです。これらのルーチンと関数は、浅い複写(あるいは、この問題のための深い複写)の後で複写されません。
深い複写は、複写されているオブジェクトの構造全体を推移します。つまり、もし私たちが 100 個の要素を持つリンクリストを深く複写すべきであったならば、それぞれの要素(それらの 100 個全部)は、(それ自体すでに 100 個のノードを持っていなければならない)複写先へ複写されるでしょう。
Eiffel のこの特徴は、他の伝統的な言語と他のオブジェクト指向言語でさえも、Eiffel 自体を分離し始める点です。あるオブジェクトを推移しそのデータのすべてを他のオブジェクトへ複写する能力は、プログラマに、推移的な手続きを自分で書かなければならないプログラマが持つ、かなりの時間を節約させる非常に有用な能力です。
深い複写がどのように働くかをさらに良く示すために、x と y が型 LINKED_LIST のオブジェクトであるという、下の状況を考えてください。
![]()
もし、いま、私たちが次のように書いたならば、
x.deep_copy( y )私たちのオブジェクトは、いま、次のように見えるでしょう。
![]()
オブジェクトを複製することの意味論は、オブジェクトをすでに存在しているオブジェクトへ複写する代わりに、新たな対象が複製元から生成(複製)されるということを除き、複写と類似しています。これを実行するために、すべてのクラスで利用可能な特徴は、限定的に、浅い複製と深い複製を実行する clone と deep_clone です。もし対象がすでに存在する構造を指すようなことが起きれば、その構造は失われることになり、そして複製元の新たな複製<clone>が対象によって参照されることになるでしょう。
![]()
複写に関係する前の節からの例を用いると、もし私たちが x.deep_clone (y) と書くべきであったならば、この結果は次のようになったでしょう。
![]()
一方で、もし私たちが浅い複写である x.clone (y) を書くべきであったならば、結果は、深い複写のものとは異なっていたでしょう。浅い複製の後の、新たな x と y の参照をよく観てください。
![]()
複製された y のポーションだけが y によって参照される直接のオブジェクトであるから、その結果は、上で示されています。本質において、私たちは、y が参照している、すでに存在するリンクリストを参照する新たなヘッダを生成しました。
等価性のために、オブジェクト同士を比較するための機構が、提供されています。もう一度、浅い等価性と深い等価性の意味論は、上で記述した複写または複製の特徴のものと比較できます。等価性の場合には、比較されている両方のオブジェクト(Void であってもよい)は、項目ごとを基にして比較されます。このための、すべてのクラスで理由可能な特徴は、equal と deep_equal です。
例は、次のようになります。
![]()
ここで、もし私たちが深いまたは浅い等価(比較)を実行するべきであったならば、これらの操作の両方の結果は、事実、x と y が(深くと浅くの両方で)等しい、ということになったでしょう。それらは、x と y によって参照されている直接のオブジェクトが項目ごとに等価であるので、浅い等価です。つまり、x の base と y の base が等しく、x の count と y の count が等しく、x の is_empty と y の is_empty が等しい、ということです。浅い等価は、そこで止まります。
深い等価は、項目ごとの等価性のために、リンク全体にあるそれぞれのオブジェクトを推移する方向へ進みます。
![]()
浅い等価の節でも用いたこの図は、深い等価のためにも適しています。つまり、x は、y への深い等価であり、同じく浅い等価でもあるといわれます。
[ 目次 ] [ イントロ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Copyright ] [ html (full) | ps | pdf ]
[ Eiffel Liberty | GUERL | sOOap ]