ば , その数値は新しい素数て、す。その場合 , 新しい に素数 prime と , 次のオプジェクト F ⅱ te 「へのポイン 素数をもつ新しいオプジェクト F ⅱ ter を演算子 new を タ , そして , 生成のためのコンストラクタ , 破棄の 使って生成し , そのポインタを next に格納します。 ためのディストラクタ , メッセージのためのメンノヾ 関数 to をもちます。コンストラクタは , 受け取った整 ディストラクタは , そのオプジェクタを削除するだ 数を自身の素数 p ⅱ me にし , かっ , その整数値を出力 けてはなく , next がさすオプジェクトをも削除しま ストリーム co ut に渡します。メンバ関数 10 は , ほか す。 のオプジェクトからメッセージを送信される代わり ・オプジェクト Gen( ジェネレータ ) に呼び出されます。 オプジェクト Gen の動作は単純てす。それは , 所定 オプジェクトは , メンバ関数 to て受け取った数値が の整数値まての整数を次々に生成するだけて、 , その p ⅱ me の倍数かどうかを調べ , 倍数て、あれば , 次のオ クラス定義は , List7 のようになります。 プジェクトへのポインタ next がさすオプジェクトのメ このオプジェクトは , たんにコンストラクタおよ ンバ関数 to を呼び出します ( メッセージの送信 ) 。受け びディストラクタだけをもち , このコンストラクタ 取った数値が倍数て、あれば , 何もせず数値を破棄し が , 2 から引数 max まて、の整数値を生成し , オプジェ ます。 クト F ⅱ te 「群のふるいに渡します。なお , 整数を渡す なお , next がまだオプジェクトをさしていなけれ オプジェクト Filter(prime. cc から抜粋 ) #include く stream. h> / / 出力ストリームの宣言を得る / / オプジェクト F ⅱ ter の定義 class PiIter { pr ivate : int prime; / / 自身の素数を格納する F ⅱ ter* next : public: Filter(int num); Filter(void) { delete next; } void to(int num); List6 / / コンストラクタ Filter::Filter(int num) { pr ー me = n um : next = NUL し : / / 出力ストリームに渡す cout くく " [ " くく prime くく” ] " 〃メッセージの代りに使われるメンバ関数 to VOid Filter::to(int num) { if (num % prine) { / / 自身の素数の倍数かどうか調べる / / 次のふるい (F i I ter) がなければ = NUL し ) { if (next = / / 新たにふるいを生成する next = new Pi ltec(num) : } else { / / 次のふるいに渡す (*next) . to (num) : 5 ] 2 [ 9 [ ] 2 [ 1 4 [ [ ー 3 ] 9 [ ー [ 3 3 ] ] 1 ] 8 [ 9 -1 一〔 7- 2 ] 7 一 [ 9 ー ] 8 [ 0 [ 3 0 ] 6 り 1- ] 7- 〔 3 [ [ 1 2 ] 6 9 3 ー ] 7 [ 0 [ 一 1 ・ 3 ] ] 〔ーー 2 1 」 6 1- 1 1- ] 6 「 - 1 ] 7 〔 9 4 [ 7- 1- ] 5 [ 例 行 実 の ・ 5 8 6 [ 9 -4 ム 一「′ 3 9 ] 5 [ 9 グ ロ 2 ] - ー・ ] 4 [ プ [ ] 5 [ 7 4 7 一 5 [ ー 4- 5 C 十十プログラミング入門 105
オフジェクト指向システム分釿上流 CASE のためのモテル化手法 S. シュレイアー / S. J. メラー著 く主な内容項目〉 オフブエク / 、指向 1 なせ情報をモテル化するのか ? 開発 / 情報のモテル化 / 他 本位田真一 / 山口亭訳 システム分析 2 基本的考え方 A5 判 192 頁 3 オプジェクト定義 / 識別化 / 名前付け / オプジェワトの試験 / 他 、 . シュしをアー、メラーお 税込定価 2500 円 本川れ・山日ツ去 4 属性定義 / 表記法 / 発見と区分化 / 職別子 / 属性記述 / 定義域 / 他 本書は , オプジェワト指向に基づく情報のモテル化手法をシステ乙 5 関係関係の概念 / 2 項関係の形式 / 他 6 多数のオプジェクトに関係する構成サプワラスとスーハーワラ 開発 ( ソフトウェア開発 ) に用いるための実用的なハウ・ツー書です。 また , 本書のシステ乙分析のテワニッワは強力で , そのアプローチは ス / 関連付けオプジェワト 7 情報モテルの表現情報構造図 / 情報構造概念図 / オプジェワト仕 システ乙ガ要とする本質的情報を同定し , 規格化し , 確認するテワ ニッワに重点を置き , 多くのシステ乙 ( ビジネス , 工学 , 技術訓練用 様書 / 関係仕様書 / 要約仕様書 / 他 等 ) のエキスハート知識を同様なアプローチで扱うことガできます。 8 技法文書調査 / 対話 / 技術ノート / レビュー / 他 9 システム開発におけるモテルの役割開発プロセス / 分析フェーズ テータベース・システ乙の他 , 多様で複雑な問題を持つシステ乙 ( リ / 外部仕様フェーズ / システ乙設計フェース / 実現フェース / 他 アルタイ乙制御システ乙 , 設計支援システ乙 , 知識べースシステ乙等 ) にも有効に利用することガできます。 付録 ロリ侮 BASIC 入門 ve 「 4.2 / 4.5 対応版 吉川敏則 / 浅野ー志著 く主な内容項目〉 0 〃畆例立 1 システムの組み込み方法フロッピーティスワ・ハードティスワ 日 5 判 B5 判 236 頁 入門 への組み込み / ガな漢字変換の設定 / 特殊な設定 / 他 税込定価 2500 円 2 簡単な使用方法起動 / 作成 / 実行 / 保存 / 読み込み / コンバイル / タ イレワトモード / 他 3 プログラムの作成テータの入力と出力 / 四則演算 / 判断 / 繰り返 し / 配列 / 条件判断と組み込み関数 / プロシージャ / 文字列処理関数 / ファイルの処理 / クラフィッワ / 再帰的プロシージャ / 他 4QuickBASlC Ver4.5 についてシステ乙構成と組み込み / この本では , 主に初心者を対象に , QuickBAS ℃のシステ乙の組 起動とプロクラ乙の実行 / QB アドハイサ / 総合環境 / 言語使用 / 他 み込み方法から , BASIC のプロクラ乙の実際的な作成方法を , 多く の例題を用いて詳しく説明しています。初めて BASIC に触れる人 , 付録 あるいはすでに他の BASIC に慣れている人 , さらに他の言語を使い こなしている人にとっても , QuickBASlC のすばらしさは一読する 価値ガあると思います。 ※ 1990 年度版図書目録か出来上がりました。下記に、ご請求くたさい。 啓学出版 〒 101 東京都千代田区神田神保町ト 46 報なる C プログラマーをめざとに〃 C 日語学習ソフト UN Ⅸシステムの基本機能をコマンドを通じで里解し、 UN Ⅸシステム上でプログラミングができるようになるこ とを目的とした学習ソフトです 第 1 章 マイクロコンピュータ用 OS 第 2 章 UN Ⅸシステムの概要 第 3 章 システムの起動 第 4 章 ファイルシステムとその内部構造 第 5 章 シェルの使い方とコマンド IPA CAROL ℃」は、 C 言語を文法知識、プログラミング演習の両面から学習でき 第 6 章 ファイルの編集 るソフトで魂これから C を使う方、 C 言語らしいスタイルの華麗なプログラミングをめ 第 7 章 UN Ⅸの基本的なコマンド 第 8 章 文章の作成・処理・出力 ざす方むきのものです。 UN Ⅸシステムでのプログラム作り 第 9 章 C プログラマは、ポインタのポインタ、ポインタのポインタのポインタなどを自由に使 第 10 章 UN Ⅸシステムの導入と運用 いこなし、関数のポインタ呼び出しを活用し、リスト構造を使いこなし、そのうえ分か 標準学習時問 : 60 時問 適応機種 : PC ー 9801 ジトズ りやすくデバッグしやれ、プログラムを組むことが要求されます。 MS-DOS Ve 「 2.11 このソフトの学習内容は、入門編、基礎編、応用編に分かれ、 c 言語の文法全体 格 : 98 , 000 円 ( 消費税別 ) 価 を包括しています。また、内蔵の C シミュレータで与えられた問題を実行し、動作を確 C 言語関連書籍 認することで発見的学習を導くよう工夫されています。 標準学習時間 : 入門編 13 時間、基礎編 27 時間、応用編 30 時間 適応機種 . PC -9801 シリーズ C の基礎文法を豊富な例題で解説した入門書の決定 MS-DOS Ver2.11 以上 版。 B5 判 240 頁 2 , 060 円 価 格 : 98 , 000 円 ( 消費税別 ) ( 消費税込み ) 〒 164 東京都中野区中野 5 ー 62 ー 1 資料請求は、氏名・お勤め先の名称・所属・住所・電 話番号を明記し資料請求券とともに郵送または FAX お問い合わせ先 CAROL インフォメー ぐノョン 株式会社 SC 0 でお願い致します。「 C 」のサンプル版をお送り致しま TEL ( 03 ) 319 ー 6991 す。 FAX ( 03 ) 319 ー 6823 TEL08 ー 233 ー 3795 FAX08 ー 233 ー 3730 UNIX 学習ソフト lPAØQ5L 「ソフトウェア (UNIX) 」 これは、基礎編で学習した文字舅をソートするプ 0 グラムてす . このプログラムのン一ト部分を数化してください . ′・をの内も・ノ、 IPAØQOL 「 C 」 数の号物はインタの配発一により 3 書 二二ロ
C 十十 プログラミング 入門 Fig. 2 「エラトステネスのふるい」による素数の生成 整数の集合 ■オプジェクトとメッセージ こてのプログラムの設計は , 次のふたつの要素 によって進めます。ひとつはプログラムの動作単位 のオプジェクト , もうひとつはオプジェクト間の情 報交換のメッセージて、す。その動作イメージは , Fig. 3 のように示すことがて、きます。 上記のような設計により , 素数生成アルゴリズム をオプジェクトおよびメッセージて、表現すれば , そ のプログラムは , ふたつのオプジェクトおよびその 間のメッセージから構成されます。それらのオプジ ェクトは以下のようなものて、す。 ・オプジェクト Gen( ジェネレータ ) このオプジェクトは , 2 以上の整数を次々に生成し ます。その整数は , 次に説明するオプジェクト Filter のふるいにかけられます。 ・オプジェクト Filter( フィルタ ) 最小の整数 7 は素数である このオプジェクトは , ひとつの素数をもち , その て、は , それらを出力ストリーム cout に渡していま 値により , ほかのオプジェクトから ( メッセージによ す。 り ) 受け取った整数にふるいをかけます。実際は , 受 け取った整数が自身の素数の倍数て、あ要吸収 ( 無視 ) ■プログラム解説 し , 倍数てない場合に次のオプジェクトに渡します。 このようにふたつのオプジェクトとして表現され 渡す先の , 次のオプジェクトがなければ , その整数 た問題を , C 十十のプログラムとしてコード化するこ は素数てあるから , 新しいオプジェクト FiIter を生成 とにします。 します。 ・オプジェクト Filter( フィルタ ) 上記の動作を図示すると , Fig. 4 のようになりま まず , オプジェクト FiIter は , List6 のようにクラス す。そして , 各オプジェクト F Ⅲ e 「がもつ素数を集め 定義がてきます。このオプジェクトは , 内部データ れば , 目的の素数の集合を得ることがてきます。 Fig. 4 Fig. 3 オプジェクトとメッセージの並列動作のイメージ Fig. 4 プログラム p ⅱ mes の動作のイメージ Gen 素数 〇〇 0 8 最小の整数 2 は素数である 〇〇 2 の倍数を取り除く 〇 0 〇 〇 0 〇 最小の整数 5 は素数である 5 の倍数を取り除く 〇〇 最小の整数 3 は素数である 3 の倍数を取り除く 2 ′ 3 ′ 4 第 5 ′ 6 を 7.8 ′ . ′ 20 ′ 21 ′ 22 を F 搬・「 2 を 21 を 3 21 ′ 03 ・ am cout 21. 2 104 CMAGAZINE 19 6
C 十十 プログラミング 入門 オプジェクト Gen(prime. cc から抜粋 ) / / オプジェクト Gen の定義 class Gen { private : P ⅱ ter* next; public: Gen(int max) : Gen(void) { delete next; } / / コンストラクタ Gen : : Gen (int nax) { cout くく "prines [ 1 ド / / 1 は特別な素数 next = new FiIter(2) : for ( i nt n = 3 : n ← nax : n + = 1 ) { / / 最大値 max までの整数を次々に / / 生成し , ふるい (F i 1 ter) に渡す (*next). to (n) : List7 main(p 「 ime. cc から抜粋 ) List8 〃関数 main void nain(void) { Gen aGen()0 の : / * 500 までの素数 ( Primes ) を得る * / ためのメッセージは , 実際には , オプジェクト Filter ジェクト指向言語のプログラムにしばしば使われる のメンバ関数 to の呼び出しになります。ディストラク スタイルてす。これを , C 十十のコルーチンパッケー タは , オプジェクト F ⅱ te 「のディストラクタ同様 , next ジなどといっしょに使えば , C 十十ても並列動作オプ がさすオプジェクト FiIter も削除しようとします。そ ジェクトのプログラムが記述てきることになります。 れゆえ , オプジェクト Gen を削除すれば , それにつな これらは , とくに , シミュレーションなどのプログ がる全オプジェクトが連続して削除されます。 ラムの記述に便利てす。 ・関数 main ほか 終わりに 関数 main(List8) は , 素数の最大値を与えて , オプ ジェクト Gen を生成するだけてす ( 注 3 ) 。後の処理は オプジェクト Gen および F ⅱ te 「に任され , 関数 main は 今回は , 抽象データ型を組み合わせ , 作成したプ 何もしません。また , オプジェクト Gen の生成は , 関 ログラム , クラスをプログラムの動作単位にみなし 数 main 中てされる必要はありません。以下のよう たプログラムを示しました。 次回は , 本誌の特集が GNU ということてすから , 本連載ても GNU に関係した g 十十 , libg 十十などを中 Gen aGen(500); 心に , C 十十のクラスライプラリを紹介しようと考え VOid ています。 main(void) { } 大域オプジェクトとすることもてきます。 [ 参考文献 ] なお , このようなプログラミングて重要なのは , ( 1 ) Lippman,S. B. , C 十十 PRIMER, 〃 Addis これらのオプジェクトの動作に逐次処理の必要がな on-Wesley , 1989. いことてす。すなわち , 各オプジェクトは , 互いに ( 2 ) 淵ー博監修「並列論理型言語 GHC とその応用』 ( 注 3 ) IDEA C 十十ては , 独立しており , その同期はメッセージのみて取られ スタックの容量の関係て , 共立出版 , 1987. 最大値は 50 ( 耳呈度に制限さ ます。これらのプログラミングは , 最近の並列オプ れる。 106 CMAGAZINE 19 6
語てはデータ構造をもった関数宣言がて、き る。関数名はデータ構造のメンバ名と同様 にプライベートな名前空間を使う。呼び出 す関数を指定するには window. open( ) のよ うに型名を使うか , new window. close( ) の ようにデータ構造の実体名を使う。そうす ればオプジェクトがいくつあっても , ( 関数 名の ) 衝突や読む人の混乱を心配しないて、 , open や close などの簡潔て表現力のある名前 を使える。 ANSI C て、さえも , この方法て、関数グルー プのカプセル化が可能だ。すべての関数を 別ファイルへ入れて static 宣言をする。そし て , 可視にしたい関数へのアドレスを保持 している構造体名だけを extern にする。 struct Win { Window * ( *open)(void) ; void (*close)(Window * ) ; &close, &open, extern struct Win Win 体に似たトランスファベクタが付帯する。 各オプジェクトには , 上記の例て、の C の構造 は , こんなことは自動的に行われている。 実は C 十十などのオプジェクト指向言語て、 の形式も書ける。 形式だけて、はなく , 旧来の (*Win. open)( ) 出すことがてきる。 ANSI C て、はこの簡単な open ( ) のような式を書けばこの関数を呼び のあるヘッダをインクルードすると , Win. この宣言 ( もちろん初期値のない宣言 ) なぜか ? こて、継承の登場となる。 既存のオプジェクトから新しいオプジェ クトを導出すると , そのすべての関数を継 承する。しかし , 継承したいずれの関数も 新しいオプジェクト用の新バージョンによ ってオーバライド ( 置き換え ) 可能だし , オリジナルのオプジェクトにはなかった関 数を追加することも可能だ。新しいオプジ ェクトに付帯するトランスファベクタは , 開始時には旧オプジェクトと同じて , 継承 14 CMAGAZINE 19 6 した各関数のアドレスは旧オプジェクトの 対応する関数のアドレスと置き換えられる。 新しく追加される関数のアドレスは最後に つけ加えられる。 この機構によってメソッドの動的パイン ディングが可能になる。実際のオペランド が旧型か新しい型のオプジェクトか不明て、 あってもメソッドを起動する式を書ける。 この場合 , 各型の ( オプジェクトの ) 実体 にはどのトランスファベクタを使うかを指 定するフィールドがある。トランスレータ がメソッドをコールするために生成するコ ードて、は , このフィールドがトランスファ べクタを決定するために使われる。そして このコードが適切なべクタのメンバを使い どの関数をコールするか決定する。 次のコードはそのための難解な C コードて、 ある。 (*object—>vecto 「 . function)( ) それほど大きな違いがあるわけて、はない が , 直接アドレスをトランスレータがわか っている関数の呼び出しに比べて , このよ うな関数呼び出しは時間がかかる。しかし , C 十十には明示的ならびに暗黙の関数コール が山ほどある。暗黙のコンストラクタやデ イストラクタ呼び出しをあまりに使いすぎ ると ( コンストラクタやディストラクタを もつクラスのオプジェクトを作成しすぎる と ) , 一見エレガントに思えるオプジェクト 参照が , 実際には表面下 ( C レベル下て、はな いが ) て、パフォーマンスを劣化させるよう な大量のコード生成を引き起こす。 とはいえ , たいていの場合 , C 十十は以上 のようなことは非常にうまくこなしている。 トランスレータは , どのメソッドをコール するかを正確に決定て、きるときにはそれを 直接コールする。メソッド参照のオーバロ ーディングを使おうと凝った場合だけ , 対 価を支払わなければならない。この対価は 思ったより高くっくが , ちょっとしたトレ ニングをすれば支払わずにすむ。 そのほかのオプジェクト指向言語は柔軟 性の点て、劣っている。たとえば Smalltalk て、 は , トランスレーション時点て、は型づけさ れない。オプジェクトへメッセージを送る ときにはどのメソッド名も指定可能だ。し たがって , ランタイムシステムのために 各オプジェクトごとにいちいち全メソッド のリストからメソッド名を探す準備が必要 になる。この場合 , トランスファベクタへ の固定オフセットはない。このとき , その オプジェクトには指定したメソッドの実体 がない可能性もある。その場合 , ランタイ ムシステムはパニックに陥るしかない このような言語て、の利点は , 少しずっメ ソッドを追加してオプジェクトをインクリ メンタルに改良 ( 工ンハンス ) て、きること にある。欠点は , 予期しないメソッド参照 の発生によってプログラムがいつ咳 ( パニッ ク ) をするかわからないことだ。もちろん単 純な手続き言語に比べてパフォーマンスは 大幅に低下する。 界における の採算性 継承はとても華やかて、目を引く。オプジ ェクト指向プログラミング派は , コードの 再利用性が向上するからパフォーマンスが いくら低下してもかまわないと納得してい る。彼らは非常にうまく作られたルートか ら派生した , オプジェクトツリーの理想的 な例を挙げてくれる ( Smalltalk システム自 身が継承の可能性の好例だ ) 。 しかしそれは眉唾ものだ。実世界の例て、 継承が採算に合うのは特定の場合に限られ ている。多くはオプジェクトのツリー型を 取るわけて、はなく , むしろデータ型とメソ ッドて、構成される 2 次元配列て、ある ocircles ( 円 ) , squares ( 四角形 ) , triangles ( 三角 形 ) に対して draw ( 描画 ) , move ( 移 動 ) , rotate ( 回転 ) を行う場合を考えてみ ればよい。クラシックな解決方法て、は親オ プジェクトを作り , たとえばそれを図形と 呼ぶことにする。図形には位置があるのて、 すべてのオプジェクトが継承て、きる一般的 な ( 訳注 : なんにて、も使用可能な ) move メソ
ノ いメソッドを追加しなければならないとし 逆の場合もある。「 e 利 ect ( 反射 ) などの新し なれる。 義する。そうすればまちがいなく勝利者に を導出し , 変更すべきメソッドだけを再定 かっている人はたんに新しいオプジェクト べての関数を変更しなければならない。わ 数は新しいケースを取り扱うのて、 , 結局す しようとするとどうなるだろうか ? 各関 いう関数を書いたあと , 新しく図形を追加 方になる。たとえば draw と move と rotate と にだまされると , ひどいカッコて、のくくり ある。オプジェクト指向プログラミング派 になることもある ( 訳注 : TbI. 1 のような 2 次 る。この 2 次元配列要素の一部が同じ関数名 の間題に必要なのは関数の 2 次元配列て、あ 題の形状を反映しているわけて、はない のコードの重複は避けられるが , それが問 ジェクトに追加しないて、すめばラッキーだ。 質を使うことてあろう。それによって一部 共通メソッドになる ) ために継承のツリー性 ( 3b 十 5c 十 2d ) へ変換すること。ここては a が 解する ( 訳注 : 数学て、 ( 3ab 十 5ac 十 2ad ) を a ポイントは , 共通メソッドをカッコて、分 きるかどうかはわからない はいても , 完成した「 otate メソッドを共用て、 かない。共通のアンセスタ ( 先祖 ) をもって だが , そのほかの図形についてはそうはい 円の回転とはたんなる冗談て、しよう ) は簡単 仮想メソッドて、ある ) 。 ci e の「 otate ( 訳注 : 始めから作りあげる必要がある ( それらは ソッドについては導出オプジェクトの中て、 ッドを提供するのは簡単だ。そのほかのメ たら何が起こるだろう。 TbI. 1 メソッド / オプジェクト draw ー ove rotate それをルートオプ circle funcE ( funcD( funcA( たぶん , すべてのオプジェクトを変更しな ければ一定レベルの最適化も達成て、きまい 従来の例て、は円などの円形をクラス定義し , これに対する操作をメソッドとして表現し ている。この方法だと円形 ( オプジェクト ) の追加は簡単だが , 操作の追加はすべての クラスに変更を要し煩雑となる。逆に描画 などの操作をクラス定義し , その対象とな る図形をメソッドに割り当てる方法も考え られる。この方法て、は反射などの操作 ( オ プジェクト ) の追加が簡単になる反面 , 今 まて、のメソッド名から動詞 , オプジェクト 名から名詞を作成し , 動作を表す方法て、は 不自然になる。そのため , このように考え る人は多くないだろう。 オプジェクト指向プログラミングを使わ なくても変更への備えが可能だということ は単純な真実だ。一度ても関数のアドレス をパラメータとして渡したり , 一度て、も関 数ポインタテープルへのインデックスを使 ったことがあるなら , メソッドのバインデ イングを遅らせたことになる。何が変更さ れそうかあらかじめわかっていれば , その ような機構を使って心ゆくまて変更部分を 隔離てきる。つまり関数をもうひとつ書い て ( 関数ポインタ ) テープルへ ( その関数へ の ) ポインタを追加すればて、きあがりだ。 よいオプジェクト指向言語によって , 部のプログラムが読みやすくなるのを認め るのにやぶさかて、はない。このようなポイ ンタすべてが自動的に de 「 efe 「 ece ( 参照はず し ) されるのはよいのだが ( 訳注 : ポインタ がたんなる変数参照てなく , 内容をさす , つまりオプジェクトを関接参照するように なる ) , コンヒ。ュータバワーをムダな場所て 消費してはいけない triangle square 元配列になる ) 。 ったオプジェクトを作成してしまうことが この関数配列を見ていながらも , まちが funcB( funcD( funcF( funcC( funcD( funcG( Programming on Purpose 15
ウイン、 ウシステム 入門 00 て、表される座標まて、線を引くのて、すが , のとき引かれる線の太さや色 , そして引き はじめる座標といったものを保持している のがデバイスコンテキストて、す。 このように Winodws や PM て、はデータ構 造 ( 記憶域 ) とそこへの操作という関係が API の中て、きちんと整理されています。このよ うなデータ構造とそこへの操作というシス テムの構成方法をデータ構造指向といいま す。アプリケーションプログラムを作成す るうえて、こういった事柄を意識しているこ オプジェクト指向 ? とはよいことて、す。 んどすべての API がオプジェクトの上て、動作 ほと 数をとる 2. の形式を使うようになり , ては API の仕様が基本的にハンドルを第 1 引 が関係しない API が少なからずあります OPM ようなハンドルの , すなわちオプジェクト 類という観点からすると Windows ては 3. の ろうと述べられています。しかし , API の分 のことをしているからオプジェクト指向だ は , Windows は単純なデータ構造指向以上 は [ 文献 7 ] て、も触れられています。そこて、 送信していたりします。この問題について は , そのウインドウに本当にメッセージを インドウのハンドルを第 1 引数にとる API て、 に , 真面目に考えてみるべき問題て、す。ウ えるのかどうかは難しい問題て、あると同時 グラミングがオプジェクト指向て、あるとい それはともかく , Windows や PM のプロ したといっていると思うと変な話て、す。 れません。日本語て、「もの」がどうした まうのて、 , こういったことになるのかもし な用語にごくあたりまえの単語を使ってし た人もいるかもしれません。英語は学術的 いう用語を使っているのて、混乱してしまっ ジェクトというふた通りのオプジェクトと ンドルて、表されるデータ構造としてのオプ クト指向の概念て、いうオプジェクトと , ハ といわれます。またこの記事て、もオプジェ よく Windows はオプジェクト指向てある するように受け取れますが , これも [ 文献 8 ] によるとオプジェクト指向の観点からそう なったというよりは ,IBM の SAA の要求に よるものだということて、す。また Windows や PM にはクラス階層のようなものは見受け られません。 Windows や PM のアプリケー ションを C 十十によって開発するためのいく つかのキットもこの点て、すっきりしていな いものが多いようて、す。オプジェクト指向 プログラミングとは何かということについ ては B. Stroustrup が [ 文献 11 ] て、述べていま す。 プラネタリウムプログラム 以上て、 , Windows のアプリケーションを 開発する際に知っておくべき事柄について ひと通り紹介しました。実際にウインドウ システムのプログラミングを覚えるには , そのソースプログラムを見るのがいちばん 早いかもしれません。私も以前 Macintosh の ツールボックスを使ったプログラムのソー スとにらめっこしながらイベント駆動モデ ルを覚えた記憶があります。 SDK にもいく つかのプログラムのソースが提供されてい ますし , 「参考文献」て、あげたような文献を 参考にするのもよいかもしれません。 本記事て、も , アプリケーションの一例と して MS-Windows のもとて、動作するプラネ タリウムプログラムを紹介します。プログ ラムの作成にあたっては [ 文献 1 ] に紹介さ れている PC ー 8001 用の「マイコンプラネタリ ウム」を参考にしています。今回のプログラ ムは , 実行したときの時刻の星空を描き出 すというものて、す。恒星位置の計算方法な どについては [ 文献 1 ] , [ 文献 2 ] などて詳し く説明されています。 誌面て、プラネタリウムのプログラムを 1 行 1 行追っていくだけの余裕はないのて , 実際 にソースを見ようという人のために , てき るかぎりソースにはコメントをつけ加えて こては , バックグラウンド おきました。 処理の方法をはじめとしたプラネタリウム プログラムて、使われているいくつかの技法 について説明します。 バックグラウンドタスク プラネタリウムプログラムて、は恒星のプ ロットをバックグラウンドて、実行していま す。描画メッセージの応答もすべての星を 表示するために fO 「 (i=o; i > MAXSTARS; i 十十 ) { / * 星をプロットする * / というようなループを使うと , さすがにほ とんどの機種て、は 0.5 秒て、終わることがて、き ません。したがってバックグラウンドて、恒 星をひとつずっプロットしていくことにな ります。 イベント駆動モデルて、は , GetEvent( ) 関 数に , イベントが何も発生していないとき にはヌルイベントを返させて , システムが 何かイベントが発生するまて何もしないて、 止まっているようなことがないようにして いることがあります。アプリケーションか らはヌルイベントを拾うことて、簡単なバッ クグランド処理を行うことがてきます ( ヌル イベントに対応する処理がほかのイベント に対応する処理と同様に短い時間内に終わ らなくてはならないことは明らかてしょ う ) 。というのも , ヌルイベントの発生回数 がおそらくすべてのイベントの中ていちば ん多いからて、す。ューザがキーポードもマ ウスもさわっていなければ , ヌルイベント 以外のイベントはほとんど発生しません。 ところが ,Windows の GetMessge( ) はこの ヌルイベントあるいはヌルメッセージとい ったものを読み出すことは決っしてありま せん。あまった時間をいったいどうしてい るのてしようか。 Windows はその時間を利用して疑似的に マルチタスク実現しています。あるアプリ ケーションが GetMessgae( ) を呼び出したと き , ューザがほかのアプリケーションの操 作をはじめれば処理はそのアプリケーショ 特集最新ウインドウシステム入門 59
広い意味ては , スカラーデータオプジェ クトの宣言をするたびに継承が使われてい る。 FORTRAN 時代から手続き型の言語て、 は論理型 , 整数型 , 浮動小数点型などの各 種の演算型を各種のサイズて提供している。 さらにより新しい言語てはオプジェクトが 格納される領域のアドレス ( ポインタ ) を扱 うことさえ , ある程度可能になっている。 各スカラー型は等値比較や加算などの各種 演算をサポートし , 型どラしの変換やひと つの式の中ての演算子を挟む型の混合 ( 訳 注 : 型 A 演算子型 B) については固有 のルールがある。 したがってコード中に int x と書くと , す ぐに (int の ) 属性とメソッドをたくさん継承 する。この宣言により作り出された x は , そ のまますぐにプログラム中に使うことがて きる。そしてこの x の有効範囲や有効期間は 宣言て、決められているのて , プログラム中 て , それらについての特別な記述は不要て ある。このように宣言時点て多くのものが 得られるわけだが , これは言語設計時に決 められている。 しかし , 必要なもの以外も得てしまう。 実際のプログラムては , x が int て表現可能な すべての値を取るのはまれだ。そのため事 実上意味のない値 ( int の部分集合 ) がスト アされるのを避けるコードを追加しなけれ ばならないこともある ( 部分範囲を定義可能 な言語もある。これは有益てある。しかし 以前に指摘したように , 部分集合すべてが 部分範囲とは限らない ) 。同様に , x の値を y に格納された値に加算してはいけないとい う制限や , 17 て割ってはいけないという制 限が場合によってはある。いずれにしても , 必要とする属性とともに int から , 以上のよ うな不要な ( コード ) を書く許可も継承する わけだ。 もうひとつ云統的な の方法 利用価値があるものを継承するもうひと つの伝統的な方法は , サポートライプラリ を呼び出すことだ。 C プログラムて標準ヘッ ダ stdio. h をインクルードすると , 日 LE とい う型定義 ( とそのほかのいろいろなもの ) が 得られる。有効なファイル名を使って fopen をコールすると日 LE データオプジェクトへ のポインタが返るのて , このポインタを各 種の関数へ渡せばオープンしているファイ ルの内容をいろいろな方法て操作てきる。 たったひとつの # inc 旧 de ディレクテイプて得 られるサービスを自作しようとするなら , 数ベージにも渡る宣言 , 数 K バイトものコー ドが必要となる。 もちろん FILE は int よりさらに余分なもの を提供しすぎている。特定ファイルに対し ての操作ては , ( あなたに代わって ) 標準 C ライプラリが提供しているもののほんの一 部しか使用されない。たとえば , 名前と住 所のシーケンシャルファイルを取り扱うオ プジェクトを自分て定義をする場合には , こんな機構すべてを提供しないだろう。あ なたが書くコードの一部はまちがいなく継 承パワーを制限するようになっている。 指摘したいのは , 継承をいっても使って いるということだ。この概念にはなんら難 解なことはないし , 使用上の困難もありえ ない。しかし , 継承した型から新しい型を 導出していることが多いのにはなかなか気 づかない。たとえば , あなたのコードが•x には int とほとんど同じ動作をしてほしいが 以下の部分だけは別〃 , またはこれは日 LE とほとんど同じだが , 以下のような厳しい 制限があるクというような記述をすること がある。汎用的な言語に付属するオプジェ クトはあまりに汎用的すぎるのて , 使うと きになんらかの制限をつけるべきだ。 のより正確な オプジェクト指向プログラミングの中心 テーマは , 自前のオプジェクトを作成する ことだ。そうするとコード再利用の可能性 が約束される。あなたがしたいことのほと んどを行うオプジェクトを , リサイクル可 能なときに再利用するのだ。もしそのオプ ジェクトが , あなたがやってほしいことと まったく同じなら , ただて目的達成だ。実 際には滅多にそうはいかないのはご存じだ ろう。目的におおよそ合致したオプジェク トの属性すべてを継承し , この属性を修正 して完全に目的に合致するオプジェクトを 導出てきる言語ならばよろしい これが先に簡単に触れた継承のより正確 な意味だ。前から述べていたことと同じこ とだが , より様式化 (stylized) され , 集中化 され (centralized) ている ( 様式化は抽象化の 一形態て , 集中化はカプセル化の一形態 ) 。 継承したものをどう編集したいかをはっき り考えさせてくれるのはオプジェクト指向 プログラミングのよい点だが , そのかわり に単純な行為まてが見えにくくなり効率が 低下するのは困った点てある。 効率低下の原因は何だろうか ? 複雑な ケースも取り扱う用意のある言語て , 何か 単純なことをしようとするとそうなる。あ なたの本当にしたいことが単純てあるとト ランスレータに伝わらないと , 安全のため に汎用的な機構をすべて使わなければなら なくなり , パフォーマンスの低下は避けら れない オプジェクト指向プログラミング言語に おける効率低下の最悪の原因のひとつは , オプジェクトとメソッドをマッチさせる機 構 ( 訳注 : オプジェクトへのメソッドの割り 付け機構 ) に潜んている。これが何を意味 し , なぜ問題なのかを解説するためには少 し前に戻らなければならない 先月号ては関数をグループ化し外部名の 名前空間ての混乱を最少にする方法につい て解説した。結合 (coupling) と団結 (cohe sion ) の原理をおのおのの関数同様にグルー プにも適応し , ひとつのグループ内の関数 を相互に関連させることが望ましい。典型 的なグループては , 関数はすべて , あるデ ータ構造を操作する ( そのほかの関数はこの データ構造の内部を知る必要はない ) 。 カプセル化をうまくサポートしている言 Programming on purpose 13
『 lnherit it 』 COMPUTER LANGAUGE Jan. 198 by P. J. PIauger 野口修男訳 / 福富寛監訳 のめ 今回は 3 回連続シリーズの最終回。 4 月号ではコードへ抽象を導入する方法とその 時期についてのシンプルなガイドラインを , 5 月号ではプログラムの各部分をカプ セル化する方法とその時期についてのガイドラインを解説した。今月号では , プ ログラムを改良するために継承 ( ⅲ heritance ) をどう使うかを考察して締めくくる。 プジェクト薯 プログラミンク信の ねじ曲がった 抽象化とカプセル化 , そして継承という 3 つの用語をよく耳にするようになった。ソ フトウェア設計の専門家がコンビュータブ ログラムの複雑さをコントロールするには , この 3 つのテクニックをときどき振り返って 考えてみなければならない。このようなス タイリッシュな考えには基本的には賛同す るが , 言葉だけてはよい設計は成り立たな い。おのおののテクニックがいつ役立ち , いつ役立たないか , というなんらかの理論 をもたなくてはいけない。そのためにテク ニックごとの「方法」とともに「時期」に焦点 一般にオプジェクト指向プログラミング 信奉者は一致して , 3 つのテクニックをすべ てサポートしてこそ , その言語がオプジェ クト指向てあるという。この意見には賛成 いただけないのは , 彼ら信奉者がねじ 曲がった憶測をとおして到達した誤った換 質換位表現 (contrapositive, 訳注 : 論理学 用語て , 「 A は B てある」を変換した結果が「 B てなければ A てない」という表現になる。た とえば , 「人間は哺乳類てある」から「哺乳類 てなければ人間てはない」を導く ) , つまり オプジェクト指向言語てないと , この 3 つ のテクニックは使えないという表現だ。彼 らは適切なオプジェクト指向言語を使って 書かない限り抽象化もカプセル化も継承も 使えるわけはないと決めつけている。 ナンセンス / 私たちはプロとしてのプ ログラミングキャリアのほとんどの期間 , これらのテクニックを使っている。よい旨 語を使えばよりうまく使える ( もっとも , よ い言語を使ったからといって必ずしもうま く使えるとは限らないが・・・ れらのテクニックはすべて昔からあるもの だ。 、もつ意味の「」 前号まての 2 回に渡って , 抽象化とカプセ ル化の使用例をいくっか挙げたが , 継承は いろいろなところて日常的に広く使われて いるし , オプジェクト指向プログラミング の世界においては , もう少し厳密な意味も ある。この用語に 2 重の意味があることが混 乱に拍車をかけている。 を当てた。 12 CMAGAZINE 19 6
MS-Windows プログラミンク入門 岡坂史紀 / 株シンフォニ MS-Windows や OS / 2 Presentation Man くつかあります。ひとつは , ウインドウシス ager(PM) といったウインドウシステムのプ テムのプログラミングモテルを理解すること。 ログラミングをはじめて経験するプログラマ いまひとつは , 膨大なシステムのファンクシ には乗り越えなくてはならないハードルがい ョンを頭の中で整理できるかどうかです。 簡単に購入てきる価格てはありません。い とはオプジェクトを表す ID , あるいはニッ つばう , 米国て発売が開始されている MS ー クネームだと考えておけばよいて、しよう。 C 6.0 にはそれらのライプラリやツールがは オプジェクトとハンドルの関係は , 後て API Windows や PM< キーワードをふたっ挙 じめから含まれています。国内てはどの時 を整理するときにも必要になるのて、 , この げるとしたら , ひとつは「統一されたユーザ 期に 6.0 がリリースされるのかわかりません 程度には理解しておいてください インタフェイス」 , もうひとつは「デバイス が , いずれにしても , これからは個人ユー プロクラミングモデレ インデイベンデント」ということになるてし ザのソフトウェア開発も一部は Windows や PM べースに移行していくことになりそうて よう。これはユーザにとって好まれること す。そのような状況もふまえ , 本稿ては てあると同時に , アプリケーションプログ ウインドウシステムのプログラミングは Windows や PM のアプリケーションプログ ラマにとっても利益となるはずてす。とは 一般的に , 特別なプログラミングモデルに ラム作成におけるいくっかの基本的な事柄 いうものの , ューザインタフェイスが統一 従って行わなければなりません。そのモデ を紹介していきます。 されたものになるかどうかはプログラマの ルは , 「イベント駆動モデル」と呼ばれてい 責任てすし , デバイスインデイベンデント ます。イベント駆動モデルのプログラムは , オプジェクトとハンドル にするためには , いままては気にしていな 「ユーザがマウスカーソルを移動させたりキ かったような部分にまて気をつけなくては ーポードを押すなどのイベントを受け取っ いけない場合もあります。 Windows や PM のプログラミングては「オ ては , それに対応して何らかの動作をする 現在 , Windows や PM のアプリケーショ プジェクト」と「ハンドル」という用語によく ということを繰り返す」構造になります。そ ン作成には , パソコンメーカー各社から提 出会います。オプジェクトは , ウインドウ れによってアプリケーションがユーザと対 供されている Windows あるいは OS / 2 用のソ やビットマップといったあらゆるデータ構 話的に動作てきるようになるからてす。イ フトウェア開発キット ( SDK ) が必要てす。 造を含んています。そしてこれらオプジェ べント駆動モデルて、は , プログラムは大ま SDK にはそのための「ライプラリ」や「開発ッ クトにアクセスするには , そのオプジェク かにいって初期化部分とイベントループに ール」がセットされているのてすが , 個人て トのハンドルが必要になります。ハンドル よって構成されます。 54 CMAGAZINE 1990 6 はじめに