
![]() |
|||
|
コンポジションは、内蔵したいインスタンスをメンバ変数にすることによって実現されます。大きなオブジェクトを内蔵する場合は、スタック領域の圧迫を避けるためにコンストラクタとデストラクタで new/delete を使います。 |
|||
![]() |
|||
| このトピックでは次の用語を覚えます: | |||
|
|||
![]() |
|||
| private メンバによるコンポジション | |||
|
「めがね (EyeGlasses)」クラスを考えてみましょう。めがねはレンズとフレームと小さな蝶番とネジからできています。話を単純にするために、「めがねは2枚のレンズから構成される」ということにしましょう。これをコンポジションで表現します。 |
|||
|
まず、「レンズ (Lens)」クラスがあるものとします。これが「めがね」クラスの構成要素となります。「レンズ」クラスは次のように宣言されているものとします(定義も必要ですが、ここでは省略します)。 |
|||
|
||||
|
「レンズ」クラスから「めがね」クラスを作るには、「レンズ」を「めがね」のメンバ変数にします。つまり、「レンズ」クラスのインスタンスを「めがね」クラス宣言に private メンバとして記述します。「レンズ」は左右2枚必要なので、「めがね」のクラス宣言は次のようになります(定義も必要ですが、ここでは省略します)。 |
|||
|
||||
| スタックの圧迫を避ける | |||
|
上のように private メンバとしてコンポジションを記述するのは、「レンズ」オブジェクトのサイズが小さいときだけです。オブジェクトのサイズがあまり大きくなるとスタック領域を圧迫してしまうためです。構成要素のオブジェクト(ここでは「レンズ」)が大きいときには、これらをヒープ領域に確保するようにします。 |
|||
|
ヒープを使ってコンポジションを行うためには、次のように private メンバとして「レンズ」オブジェクトへのポインタを記述します。 |
|||
|
||||
|
実際にヒープ上でインスタンスを確保するのは new 演算子です。ヒープ上のインスタンスを解放するのは delete 演算子です。「めがね」の構成要素である「レンズ」の確保・解放を行うために、コンストラクタとデストラクタを使います。具体的には、次のようになります。 |
|||
|
||||
|
コンストラクタでは、「めがね」オブジェクトを使用可能にするために new を使って「レンズ」オブジェクトの確保を行っています。レンズは2枚あるため2度 new が使われています。new はヒープ領域が不足している場合には失敗します。そのため、確保に成功したかどうかを判定し、失敗時にはエラー処理を行う必要があります。 デストラクタでは delete を用いて「レンズ」オブジェクトを解放しています。確保に失敗したときのことを考えて、ポインタが有効なアドレスを指しているときだけ解放するようにしています。 |
|||
| もっと詳しく知りたい人は次の用語について調べると良いでしょう: | ||||
|
||||
(「オブジェクト指向のはなし」は1999年2月から2000年4月にかけて作成されたコンテンツです。)