#3 行列操作ライブラリの設計(2) (1999/06/21 初版)
 オブジェクト指向プログラミングでは、情報を処理するのにそれらを要素に細かく分 
解するのではなく、ある程度まとまりのある集合を単位にして処理を進めます。このよ 
うな要素に分解しきれない単位をオブジェクトといいます。プログラミングで情報とは、
データとそれらを操作する関数のことを意味します。データは情報自身の内部状態(属 
性)であり、関数はその状態を変化させる操作(動作)です。つまり、データと関数と 
を1つながりにまとめたものがオブジェクトです。 

3.1.1 クラス

 C++のオブジェクト指向プログラミングの中核となる概念がクラスです。クラスとは 
組み込のデータ型と同じように振る舞うことのできる「データ型」です。ここで設計す 
る行列クラスMatrixでは次の宣言 

Matrix a; 

で適切なサイズの行列の実体(オブジェクト) aが作られます。また行列要素の参照は 
a[i][j] で行うことができます。 
 また2つの行列a、bの和、差や積は、「+」、「−」や「*」演算子を使った演算 
が可能で、その演算結果を 

cout << a + b; 
cout << a - b; 
cout << a * b; 

のように、適切に書式化して標準出力することが可能になります。これは、組み込型の 
intdouble 型と同じく「完全」なデータ型となっています。 

 クラスとは、データ構造とそれを操作する演算(あるいは関数)がセットになって定
義された「型」です。クラスは「ユーザ定義型」あるいは「抽象データ型」とも呼ばれ
ます。そして、クラスが定義した型宣言によって生成した実体 (組み込型の場合 での
変数)のことを「オブジェクト」あるいは「クラスのインスタンス」といいます。 


 オブジェクト指向プログラミングでは、データ中心のプログラミングになります。デ 
ータとその動作(関数)は密接にリンクされています。オブジェクトは自らが振る舞う
べき動作を理解しています。換言するとオブジェクトは自身の振る舞いに責任を負って
います。 

 この様なプログラミング観は、グラフィカルなインターフェースを備えたコンピュー 
タ・システムの利用者にとっては馴染みあるものです。例えば Microsoft Windows 95 
では、アプリケーション・ソフトウェアで作成したファイルはアイコンで表示されてい 
ます。これらのファイルを編集するには、まずマウスでファイルをポイントします。そ 
れからファイルをダブルクリックすることでそのファイルに専用のソフトウェアが起動 
されます。つまり最初にファイルが指定され、それに対する動作が決まります。 

 また多くのエディタやワープロ・ソフトウェアでは、編集中の文書の一部(文字列) 
を選択表示した状態でマウスの右ボタンを押すと、「切り取り」・「コピー」などのメ 
ニューが表示されます。一方、選択しない状態では、「張り付け」などの別のメニュー 
が表示されます。指定した現在の状況に対して可能な操作が決まります。オブジェクト
指向プログラミングでは、まずオブジェクトがあり、それに対する操作が決まります。


 Cプログラミングでは、関数中心のプログラミングになります。Cではプログラミン 
グの単位は関数であり、プログラムは関数群を組み合わせて作られます。このときデー 
タは関数が引き起こす動作のための補助的役割に過ぎません。これは、動作だけを追い 
かけるプログラミングです。そのためCやその他の手続き型プログラミング言語では、 
アクション指向のプログラミングになります。 

 これに対してC++のオブジェクト指向プログラミングでは、クラスの設計が中心とな 
ります。クラスはプログラミングが対象とするモノの概念をデータ型として表現する仕 
組みです。オブジェクト指向プログラミングは、「名詞的」といわれます。クラス設計 
ではプログラムのシステム仕様の中の名詞に着目してクラス群を作ります。クラスは名 
詞で、その動作はその名詞と関係のある動詞です。そしてクラスから生成されるオブジ 
ェクトを組み合わせて、プログラムシステムを構築します。 

3.1.2 抽象とカプセル化

 クラスは関連するデータとそれらの操作(関数)をパッケージにして1つのデータ型 
をつくります。クラスのデータ成分をデータメンバと呼び、関数成分をメンバ関数と呼 
びます。この機能によって、プログラムが描く対象を抽象化して表現することができま 
す。抽象化は人間誰もが自然に身につけている認知能力の1つです。私たちは実世界の 
あらゆるものを、単なるバラバラな要素の集合としてではなく、意味のあるまとまりと 
して認識します。 

 この抽象化の説明として少し逆説的ですが、脳の一部の機能障害のためにある特定の 
モノに対して抽象化ができなくなった人の例を引き合いにしましょう。 
 これは、松岡正剛著:『知の編集工学』(朝日新聞社)の中にある話の引用です。あ 
る精神科医の患者で、その人は電話機がまったく認知できないという話です。どういう 
ことかというと、「この机の上にあるものを言ってください」という医師の質問に対し 
て、その患者は次のように答えます「ええっと、机の端に黒い盛り上がったものがあり 
ますね。それが少し曲がっていて、紙のような文字が書いてある平べったいものとつな 
がっていまして、……」。というようにこの患者さんは電話機という抽象化ができなく 
なっています。この様に私たちはものごとに対してそれが持つ概念(意味内容)を1つ 
の名前で表現し理解します。この人間の自然な意識行為をプログラミングで模倣するの 
がクラスであり、クラスは実世界の概念を型定義します。 


 また私たちはものごとを抽象化すると同時に、分類します。共通した属性を持つモノ 
同士は同じカテゴリに属していると理解し、違う属性に注目して個々の差異を理解しま 
す。オブジェクト指向プログラミングでは、継承という概念を使って、この様な分類を 
表現します。継承は、既存のクラスの性質を受け継いで、それに新たな機能を付加した 
新しいクラスをつくりだすことができます。 


 クラスが定義する型によって生成されたオブジェクトはデータとその振る舞い(関数) 
が密接にリンクしています。データはオブジェクトの属性であり、関数はその属性を変 
化させる操作(動作)です。このため、その型を利用する外部プログラムはその操作法 
(メンバ関数)だけを知っていれば済みます。なぜなら、クラス内のデータメンバを操 
作するのに必要十分なメンバ関数が用意されていれば、直接データにアクセスする必要 
はないからです。つまりその型を使用するプログラムから、オブジェクトの内部データ 
の詳細にアクセスすることを禁止することができます。従って、クラスが定義する型の 
内部実装の詳細を外部から隠すことが可能になります。これをカプセル化あるいは情報 
隠蔽といいます。 

 例えば、私たちは「行列」の数学的な概念を知っています。行列の演算(足し算、引 
き算やかけ算)がどうのように行われるかを知っています。すると行列を表現するクラ 
スMatrixがそれらの演算をサポートしていれば、Matrix型のオブジェクトa,b,cに 
対して、 

c = a + b; 
c = a - b; 
c = a * b; 

といったオブジェクトの使い方を知っていればよいわけで、オブジェクトの内部がどの 
ように実装されているかといったデータ構造のレイアウト(たとえば行列要素はポイン 
タへのポインタとして表現されているなど)の詳細を知る必要はありません。 

 この様にクラスは、カプセル化(あるいは情報隠蔽)のメカニズムを備えることで、 
データの内部実装の詳細から、そのオブジェクトを正しく使うために本質的に意味のあ 
る特徴を切り離します。これにより内部データへの不正なアクセスを防ぎ、さらにクラ 
スを利用するプログラム・コードは簡略化して表現できます。ただし、そのためにはオ 
ブジェクトのデータメンバが適切に初期化されていることが前提となります。 

| 目次 | 次のページ | ページの先頭 |

Copyright(c) 1999 Yamada,K