作成日 2007/10/28
最終更新日 2009/1/19
オブジェクトの生成と動的なメモリの確保、オブジェクトへの参照とポインタ
ここでは、オブジェクト指向プログラミングの基礎である動的なメモリの確保・解放とポインタについて説明します。
クラスからオブジェクトを生成するということは、メモリを確保し初期化することを意味します。
そして、オブジェクトの破棄はメモリを解放すること意味します。
確保したメモリ領域にアクセスする際にポインタを使用します。ちなみに、ポインタはC言語のポインタ(※1)です。JavaやVBAではポインタを直接扱うことはないのですが(※2)、ポインタを理解していないとプログラミングができないです(※3)。
オブジェクト指向プログラミングではクラスからオブジェクトを作ることは、必要なサイズのメモリを確保し、確保したメモリ領域を初期化するということになります。
もう少し詳しく説明します。
「クラス図とER図とクラスの抽出 の 表1 クラス図とER図の対応表」を見て欲しいのですが、クラス図のオブジェクトはRDBのレコード(行)と同じようなものであると言っています。
ということは、クラス(RDBのテーブルに相当)からオブジェクト(RDBのレコードに相当)を作るには、そのデータ(RDBならレコード内のデータ)を保持する記憶領域を新しく確保する必要があるわけです。
じゃあどうするか?
メモリには使用用途によってスタック領域、ヒープ領域など(※1)があります。そのうちヒープ領域は、プログラム作成者が自由に使用できる領域で、ここから、欲しいサイズ分だけ確保します(※2)。
で、その後、確保したメモリ領域を初期化するとなります。
-----
※1:他に、プログラム領域、静的領域。だるまも詳しいことは知りません。ごめんなさい。
ただ、VBAでプログラミングする際にもメモリ領域についてはある程度知っておく必要があります。
例えば、このページを読んでいる人はError
7(メモリが不足しています。)、Error
28(スタック領域が不足しています。)のヘルプに書かれている内容は理解できるでしょうか?
※2:必ずしもヒープ領域である必要はないです。実行前に必要なメモリのサイズがわかっている場合、スタック領域から確保しても良いです。
ただし、使用言語が対応している必要があります。C/C++では可能です。VB、VBA、Javaではできないです(もしかしたら、最適化の結果、ヒープ領域以外の領域からメモリが確保される可能性はあるかもしれない)。
「1.オブジェクトの生成と、動的なメモリの確保」で、オブジェクトの生成するには、メモリ領域を確保し、そのメモリ領域を確保する必要があると説明しました。
で、そのメモリ領域にアクセスする際にポインタが必要となります。ポインタとはメモリ領域のアドレスのことです。
もう少し、詳しく説明します。
「クラス図とER図とクラスの抽出 の 図1 生徒情報と成績のデータ」を見て欲しいです。
では、この図の生徒情報データにある情報のうち名前を取得するとしましょう。
で、その場合(当然ですが)どのレコードの名前なのかを指定する必要があります。
オブジェクト指向プログラミングもこれと同じです。
メモリの確保は何度でも行います。ヒープ領域のいろんなところに、データを格納している箇所があります(図1参照)。
図1 ヒープ領域にデータを格納しているイメージ図(※1、※2、※3)
で、どのオブジェクトのデータを取得したいのかを指定するときにメモリの先頭アドレスを使います(※4)。
-----
※1:この図はイメージ図です。このイメージ図では出席番号(数値型)は4バイト、名前(文字列型)に33バイト(文字列は0で終わるとする)、生年月日(日付型)に3バイト使用しています。
再度書きますがこの図はイメージ図です。VB、VBAではこうなりません。
大体、VB、VBAの日付型(Data型)は3バイトではないし…。(VB、VBAの日付型は8バイトで、日付だけでなく時刻(秒単位まで)までの情報を保持できます。)
※2:文字列ですが、これは言語によってデータの持ち方が異なります。このイメージ図はC言語でchar型で33バイトとった場合と同じです。Javaでは文字列(java.lang.Stringクラスのオブジェクト)はオブジェクトです。VB、VBAは良く知りません。(VBAのサイトなのに…。ごめん。)
日付型も、言語によってデータの持ち方が異なります。
※3:イメージ図では1つの領域は40バイトですが実際にはパディングによって増える場合があります。
※4:Javaではポインタとか先頭アドレスといった単語は出てきません。その代わり参照という言葉が出てきますが、ポインタとほぼ同じだと思ってください。
オブジェクトを破棄するときは、動的に確保したメモリを解放する必要があります。解放したメモリ領域はまたいつか確保されて…と、リサイクルされます。
動的に確保したヒープ領域上のメモリを解放しなかった場合は、徐々に使用できるメモリのサイズが減り、システムが不安定になったりします。(詳しいことはWikipediaのメモリリークのページに書かれていますのでそちらを参照願います。)
ここで重要なことは、言語により解放の方法が異なることでしょうか。
C/C++では解放は自分(プログラム作成者が解放するコードを記述する)でします(※1、※2)。
JavaやVB、VBAではメモリの解放は自動で行ってくれます。なので、メモリリークは起こらない…とはならない。解放がどのようにして行われているのかを理解しておく必要があるのですが、これは「オブジェクトが破棄されるタイミング - だるまのエクセルVBA
」で説明します。
-----
※1:Boehm GCを使用すれば解放処理を自分で記述する必要がないようです。
※2:C++であれば、スマートポインタを使用してオブジェクトの解放を自動化することも出来ます。
このページを作成するのに参考にしたページです。
ただし、だるまが以下のページをちゃんと理解してこのページを作成したとは思わないように。
このページの利用によって発生した、いかなる損害について、このホームページの作成者は責任を負いません。
このページの間違いや嘘を見つけた方、このページに書いて欲しい情報がある方は
メールをお願いします。
Microsoft 、Windows 、Visual Basic および Excel は米国Microsoft
Corporationの米国およびその他の国における登録商標または商標です。
ここではExcel® をエクセル、Visual Basic® for Applications をVBAと表記する場合があります。
Mac 、Mac OS 、Mac OS X は米国Apple Computer,Inc.の登録商標または商標です。
Sun、Sun Microsystems、サンのロゴマーク、Java、及び、Sun/Solaris/Java に関連するすべての商標およびロゴマークは米国 Sun Microsystems, Inc. の米国およびその他の国における商標または登録商標です。
Wikipedia® は Wikimedia Foundation, Inc. の米国およびその他の国における登録商標です。
その他、社名および商品名、システム名称などは、一般に各社の商標または登録商標です。
このホームページの作成者はこれらの会社とはいっさい関係がありません。