« December 2007 | Main | February 2008 »

January 2008

January 21, 2008

インスタンスはヒープ領域に作られる

**************************************************************
_/_/_/_/_/_/_/ ソフトウェア業界 新航海術 _/_/_/_/_/_/_/_/_/
**************************************************************
第198号 2008/1/21
『インスタンスはヒープ領域に作られる』
▼ まえがき
▼ [オブジェクト指向再入門] (1)良書である理由
▼ [オブジェクト指向再入門] (2)インスタンスはヒープ領域に作られる
▼ [オブジェクト指向再入門] (3)Cでのヒープ領域の使用方法
▼ [オブジェクト指向再入門] (4)Javaでも同じようなことをやっている
▼ [オブジェクト指向再入門] (5)Cは手動メモリ管理
▼ [オブジェクト指向再入門] (6)メモリ自動管理の唯一の弊害
▼ 次回以降の予告


*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
まえがき
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

蒲生嘉達(がもうよしさと)です。

いよいよ拙著「ソフト会社の心臓」が2月12日(火)に出版されます。
出版社からカバー案(↓)が送られてきました。
http://www.kei-it.com/sailing/img/soft.jpg


さて、今日は、引き続き「オブジェクト指向プログラミング」に
ついて話します。

「オブジェクト指向プログラミング」は本文では「OOP」と略します。
英語の'Object Oriented Programming'の略です。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (1)良書である理由
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

第197号でもふれた「オブジェクト指向でなぜつくるのか」(平澤章著、
日経BP社発行)を読み終わりました。

 (第197号:インスタンスという仕組みが画期的である理由
 http://kei-it.tea-nifty.com/sailing/2008/01/post_606d.html )


私は、次の二つの点で、この本は良書だと思います。

(1)
プログラミング技術であるOOPと、上流工程で使われるオブジェクト
指向技術(モデリングなど)とを明確に区別して書いています。

(2)
OOPの特徴はメモリの使い方にあると指摘し、そのメモリの使い方
の側から、クラス、インスタンス、ポリフォーフィズム、継承
などの仕組みを説明しています。

OOPをメモリの使い方の側から説明している本は珍しいと思います。

(1)については別の機会に話すとして、本日は(2)について
話します。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (2)インスタンスはヒープ領域に作られる
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

例えば、インスタンスの生成について、同書では、

> インスタンスを作る命令が実行されると、そのクラスのインスタンス
> 変数を格納するのに必要な大きさのメモリがヒープ領域に割り当てら
> れます

と説明されています。


例えば、Javaで次のように書くと、Bookインスタンスがヒープ領域に
作られます。

 Book WhyOOP = new Book(); // Bookインスタンスの作成


ここで「ヒープ領域に作られる」というところが重要です。


------------------------【基礎知識】------------------------

プログラムが動くときに使われるメモリ領域には、静的領域、
スタック領域、そしてヒープ領域の3つがあります。

静的領域とはプログラムコードやグローバル変数が格納される領域です。
スタック領域とはローカル変数、引数、呼び出し元アドレスが格納
される領域です。

それに対し、ヒープ領域とはアプリケーションが自由に使えるワーク
領域のようなもので、アプリケーションが必要とする大きさの領域を
必要とする期間保持できます。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (3)Cでのヒープ領域の使用方法
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

第197号では次のように書きました。

> Cで複雑な構造を持つデータを共用する方法は次の二つです。
>
> ・グローバル変数
> ・呼び出し元で構造体などを作り、呼ぶときにはその領域のポインタ
>  を渡す。

 ( 第197号:インスタンスという仕組みが画期的である理由
 http://kei-it.tea-nifty.com/sailing/2008/01/post_606d.html )


Cでは、ある関数内でヒープ領域を獲得し、そこに構造体などを作り、
その領域のポインタを使って様々な関数がその領域にアクセスすると
いうことをよくやります。

スタック領域に作られる変数(ローカル変数)はその関数が呼び出
されているときにしか存在しないため、一定期間データを保持したい
ときには使えないからです。

また、グローバル変数として静的領域に作ると、プログラムサイズが
大きくなるし、保守性が低下するからです。


Cでは上記処理を具体的には次のように書きます。

・malloc関数でヒープ領域を獲得する。
・その領域のポインタを引数として、他の関数を呼び出す。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (4)Javaでも同じようなことをやっている
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

実はJavaでも同じようなことをやっているのです。

 Book WhyOOP = new Book(); // Bookインスタンスの作成

というコードは次のことを意味しています。

・ヒープ領域を獲得し、そこにWhyOOPという名前のBookインスタンス
 を作る。
・Book WhyOOP には、上記インスタンスが存在するヒープ領域の
 ポインタが格納される。

そして、次に

 WhyOOP.setPrice("2400"); // WhyOOPに値段を設定する

というコードを書いたとしたら、それは次のことを意味します。

・メソッドsetPrice呼び出す。
・WhyOOPを指定する。
 つまり、WhyOOPインスタンスが存在するヒープ領域のポインタを渡す。
(Cのように明示的なポインタではないが・・・。)

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (5)Cは手動メモリ管理
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

しかし、下記の点でCとJavaとでは大きな違いがあります。

・Cでは、malloc関数で(サイズまで指定して)明示的にヒープ領域を
 獲得しなければならない。
・しかも、不要になったら、free関数で明示的にその領域を解放しな
 ければならない。


ここに2つの問題があります。

(1)他のヒープ領域まで侵入できる

Cではヒープ領域のポインタを明示的に扱えるため、自分が獲得
したヒープ領域を超えて、他のプログラムが獲得しているヒープ
領域まで参照できてしまいます。
したがって、Cでは他のプログラムが獲得しているヒープ領域のデータを
破壊するという重大なバグが発生しやすいのです。


(2)メモリ解放漏れバグ

メモリ解放漏れのバグもしばしば発生します。
特にイレギュラーなケースでメモリ解放を忘れがちです。

しかも、メモリ解放漏れのバグは見つけにくいのです。
多少解放漏れがあったとしても、プログラムを数回流した程度では、
メモリは枯渇しないからです。

つまり、通常のテストでは正常に動いていたのに、少しずつ使用可能
メモリが減っていって、長時間稼動させると妙な動きが始まるのです。
その解放漏れがレアケースにのみ通過する部分にあったりすると、
デバッグは困難を極めます。

一方、JavaなどのOOP言語ではヒープ領域の獲得と解放が自動化
されています。この自動解放の仕組みがガベージコレクションです。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (6)メモリ自動管理の唯一の弊害
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

メモリ自動管理はプログラマの生産性を向上させました。

これはOOPに限ったことではありません。
多くのWindowsプログラマがCやC++ではなく、VBを使う理由は、
VBの方が生産性が高いからであり、その生産性の高さの大部分は
メモリ自動管理によるものです。


しかし、メモリ自動管理には、たった一つだけ弊害がありました。

プログラムが動く仕組みをプログラマがイメージしにくくなったと
いう点です。

Cのプログラマは頭の中でメモリ領域をシミュレートしながら
プログラムを書いていました。

しかし、JavaやVBや.NETのプログラマの頭の中ではメモリ領域の
シミュレーションは行われていないでしょう。

そして、普段はそれでいいのです。

しかし、ときどきは必要になるのです。


したがって、私はOOPにおけるメモリの使い方の話をもう少し続けようと
思います。


*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
次回以降の予告
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

次回発行予定は、2月初旬です。

乞うご期待!!

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
本メルマガについて
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

本メルマガは2003年12月8日に創刊されました。
創刊号 http://www.kei-it.com/sailing/01-031208.html で述べたとおり、
本メルマガのコンセプトは「読みものとしても面白い慶の事業計画」であり、
目的は「事業計画の背後にある基本的な考え方を語ること」です。

したがって、第一の読者としては、慶の社員(正社員・契約社員)及び
慶と契約している個人事業主を想定しています。

また、多くのソフトウェア会社・技術者が直面している問題を扱っているので、
ソフトウェア会社の経営者、管理者、技術者にとっても参考になると思い、
第33号(2004年7月19日号)からは「まぐまぐ!」で一般の方々にも公開する
ことにしました。
「まぐまぐ!」での読者数は2007年1月19日現在、649名です。


本メルマガの内容に興味を持つであろう方をご存知なら、是非
本メルマガの存在を教えてあげてください。

(以下をそのまま転送するだけです。)
---------------------------------------------------
【お勧めメルマガ ソフトウェア業界 新航海術】
⇒ http://www.mag2.com/m/0000136030.htm または
 http://kei-it.tea-nifty.com/sailing/ または
 http://www.kei-it.com/sailing/ 
--------------------------------------------------

このメールマガジンは『まぐまぐ!』 http://www.mag2.com/ を利用して
発行しています。配信中止はこちら http://www.mag2.com/m/0000136030.htm
(但し、knextall@kei-it.com には直接配信しています。)


バックナンバーは、発行者サイトまたはブログで、体系として
見てもらいたいので、「まぐまぐ!」でのバックナンバー公開は
最新号のみとなっています。

バックナンバーブログ:http://kei-it.tea-nifty.com/sailing/
発行者Webサイト: http://www.kei-it.com/sailing/
(発行者Webサイトではバックナンバーの全文検索も可能です。)


☆筆者の趣味のブログ:身近にいる小動物の図鑑☆
 http://kei-it.tea-nifty.com/small/

--------------------------------------------------
発行:
株式会社 慶
 代表取締役 蒲生 嘉達

☆ コピーや配布をされる時はご一報ください ☆

|

January 01, 2008

インスタンスという仕組みが画期的である理由

**************************************************************
_/_/_/_/_/_/_/ ソフトウェア業界 新航海術 _/_/_/_/_/_/_/_/_/
**************************************************************
第197号 2008/1/1
▼ まえがき
▼ [オブジェクト指向再入門] (1)広く深く浸透するOOP
▼ [オブジェクト指向再入門] (2)「まとめて、隠しす」はCでもできる
▼ [オブジェクト指向再入門] (3)「たくさん作る」はOOP特有の機能
▼ [オブジェクト指向再入門] (4)Cで同様の処理を書く場合
▼ [オブジェクト指向再入門] (5)インスタンスが画期的な理由
▼ [オブジェクト指向再入門] (6)現実の事象を表現できる
▼ 次回以降の予告


*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
まえがき
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

蒲生嘉達(がもうよしさと)です。

明けましておめでとうございます。

このメルマガ執筆中に初日の出を迎えました。
 初日の出の写真:
 http://kei-it.tea-nifty.com/small/2008/01/2008_32ce.html

今年も宜しくお願いいたします。


普通はここで年頭らしい話をするのでしょうが、それは次回以降に
回して、今日はオブジェクト指向プログラミングについて語ります。


「オブジェクト指向プログラミング」は本文では「OOP」と略します。
英語の'Object Oriented Programming'の略です。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (1)広く深く浸透するOOP
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

私が実際に本格的にコーディングしたことのあるプログラミング言語
はCのみです。JavaなどのOOP言語のコーディング経験はありません。

OOPについて、本メルマガでは過去に第5号で解説したことがあります。

 第5号:オブジェクト指向プログラミング
 http://kei-it.tea-nifty.com/sailing/2004/01/post_3571.html
 http://www.kei-it.com/sailing/05-040105.html


4年前(2004年1月5日発行)に書かれたこの記事は、今読み直してみても
内容的に間違えてはいないと思いますが、抽象的な説明に終わっています。
私自身も概念的にしか理解していませんでしたから。

4年前に比べて、オブジェクト指向は、現在、様々な分野(OOP、
フレームワーク、デザインパターン、UML、モデリング、設計、
開発プロセス)において広く深く浸透しています。

そこで、もう少しオブジェクト指向についての理解を深めようと思い、
今「オブジェクト指向でなぜつくるのか」(平澤章著、日経BP社発行)
を読んでいます。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (2)「まとめて、隠しす」はCでもできる
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

オブジェクト指向のもっとも基本的な仕組みは「クラス(class)」と
「インスタンス(instance)」です。


「オブジェクト指向でなぜつくるのか」にはクラスとインスタンス
について次のような説明があります。

---------------------------------------------
 クラスは「まとめて、隠して、たくさん作る」仕組み

 1)サブルーチンと変数を「まとめる」
 2)クラスの内部だけで使う変数やサブルーチンを隠す
 3)1つのクラスからインスタンスを「たくさん作る」

---------------------------------------------

オブジェクト指向の解説書には必ず出てくる説明ですが、私は以前から
このような説明が腑に落ちませんでした。

サブルーチンと変数を「まとめる」「隠す」と言っても、Cでも
static変数やstatic関数を使えば似たようなことができるはずです。

この点については、「オブジェクト指向でなぜつくるのか」でも認めて
います。

> 「まとめる」「隠す」については、C言語など従来のプログラミング
> 言語でも実現できることに気づいた方もおられるかもしれません。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (2)「たくさん作る」はOOP特有の機能
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

しかし、同書ではそれに次の文が続きます。

> しかしこの「たくさん作る」仕組みは、従来のプログラミング言語
> では実現が難しいOOP特有の機能です。


そして、同書では、ファイル操作するクラスを例にして「たくさん作る」
仕組みの便利さを説明しています。

そのクラスではファイル番号を保持する変数は一つのみです。

しかし、複数のファイルを使うようなアプリケーションからこのクラス
内のメソッドが呼び出されても以下の理由で大丈夫だというのです。

・プログラムの実行時にインスタンスが複数できる。
・呼び出し側でインスタンスを指定して呼び出すから、呼び出される
 側では、どのインスタンスに対するメソッド呼び出しなのか分かる。
・したがって、クラスの側では、そのインスタンスが複数同時に
 動くことを意識してロジックを組む必要はない。


> こうした仕組みがない構造化言語で同じ機能を実現する場合、配列
> などを使って必要な数だけ変数領域を用意しなければならないため、
> それを処理するサブルーチンのロジックも複雑になってしまいます。
>       (「オブジェクト指向でなぜつくるのか」より)

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (4)Cで同様の処理を書く場合
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

この部分を私が最初読んだときの感想は「Cでも呼び出される側は
複数同時に動くことを意識しないじゃないか。それほど画期的なこと
なのかなぁ」でした。

Cで同様の処理を書く場合には、通常は次のようにします。

・ファイル識別子を呼び出し元のローカル変数に格納しておく。
・ファイルを操作する関数を呼び出すときには、そのファイル識別子を
 引数として渡す。
・したがって、呼び出される関数の側では、異なるファイル識別子が
 同時に存在していることを意識してロジックを組む必要はない。


つまり、呼び出される関数内のファイル番号を保持する変数は、やはり
一つで済むはずなのです。


なぜ、インスタンスという仕組みがそれほど画期的なのでしょうか?
私はこの点についてもう少し考えて、分かりました。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (5)インスタンスが画期的な理由
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

呼び出し元と呼び出し先で共通して利用しなければならないデータが
ファイル識別子のように一つの場合は、CでもOOPでも大差ありません。

しかし、複雑な構造を持つデータを共用する場合には、OOPが威力を
発揮します。

Cで複雑な構造を持つデータを共用する方法は次の二つです。

・グローバル変数
・呼び出し元で構造体などを作り、呼ぶときにはその領域のポインタを渡す。

グローバル変数もポインタ変数も共にプログラムの保守性を低下させます。

OOPにおけるインスタンス変数は必要なときだけ存在し、しかも、
複雑な構造を持てる変数です。
ローカル変数とグローバル変数のいいとこ取りなのです。

なるほど、これは便利です!

でも、Javaから入りJavaしか知らないプログラマには、この仕組みの
ありがたみが分からないでしょうね。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
[オブジェクト指向再入門] (6)現実の事象を表現できる
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

この仕組みが理解できると、「オブジェクト指向は現実世界をそのまま
ソフトウェアに表現する技術である」という、OOPについてのお決まり
の説明が理解できます。

インスタンスとは複雑なデータ構造を持ち得る仕組みです。
つまり、複数の属性を持てるのです。
その点ではデータベースのレコードに似ています。
その意味で、現実の事象を表現できるのです。

但し、データベースのレコードと違って、呼び出し元が必要とする
ときにしか存在しません。
また、データベースのレコードと違って、メソッドとそれが属する
クラスに結びついています。

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
次回以降の予告
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

次回発行予定は、1月中旬です。

乞うご期待!!

*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
本メルマガについて
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

本メルマガは2003年12月8日に創刊されました。
創刊号 http://www.kei-it.com/sailing/01-031208.html で述べたとおり、
本メルマガのコンセプトは「読みものとしても面白い慶の事業計画」であり、
目的は「事業計画の背後にある基本的な考え方を語ること」です。

したがって、第一の読者としては、慶の社員(正社員・契約社員)及び
慶と契約している個人事業主を想定しています。

また、多くのソフトウェア会社・技術者が直面している問題を扱っているので、
ソフトウェア会社の経営者、管理者、技術者にとっても参考になると思い、
第33号(2004年7月19日号)からは「まぐまぐ!」で一般の方々にも公開する
ことにしました。
「まぐまぐ!」での読者数は2007年12月31日現在、650名です。


本メルマガの内容に興味を持つであろう方をご存知なら、是非
本メルマガの存在を教えてあげてください。

(以下をそのまま転送するだけです。)
---------------------------------------------------
【お勧めメルマガ ソフトウェア業界 新航海術】
⇒ http://www.mag2.com/m/0000136030.htm または
 http://kei-it.tea-nifty.com/sailing/ または
 http://www.kei-it.com/sailing/ 
--------------------------------------------------

このメールマガジンは『まぐまぐ!』 http://www.mag2.com/ を利用して
発行しています。配信中止はこちら http://www.mag2.com/m/0000136030.htm
(但し、knextall@kei-it.com には直接配信しています。)


バックナンバーは、発行者サイトまたはブログで、体系として
見てもらいたいので、「まぐまぐ!」でのバックナンバー公開は
最新号のみとなっています。

バックナンバーブログ:http://kei-it.tea-nifty.com/sailing/
発行者Webサイト: http://www.kei-it.com/sailing/
(発行者Webサイトではバックナンバーの全文検索も可能です。)


☆筆者の趣味のブログ:身近にいる小動物の図鑑☆
 http://kei-it.tea-nifty.com/small/

--------------------------------------------------
発行:
株式会社 慶
 代表取締役 蒲生 嘉達

☆ コピーや配布をされる時はご一報ください ☆

|

« December 2007 | Main | February 2008 »