VB.NETの値型と参照型について
VB.NETで変数として宣言できるデータ型は大きく分けて「値型」と「参照型」に分けられます。 「参照型」は、初めてVB.NETを使い始めた方にとっては、なかなか理解しにくい部分でもあります。 かく言う私もそのひとりではありますが。
「値型」は変数としてよく使う、Integer、Double、Decimal、DateTime及び構造体、列挙型などで、 「参照型」はクラス、配列などです。
「値型」のInteger、Doubleなどは直感的に分かりやすいのですが、 「参照型」の実際はどうなのか理解しにくいものです。
「値型」とは変数を保持しているメモリ上に直接データをアクセスできるもので、 「参照型」とはその変数に保持しているのは、参照型データの実体を指し示すポインタ的なものです。
言葉で説明すると何のことか分かりにくいので 「値型」と「参照型」を比較する為、構造体とクラスで説明します。
以下の様な構造体とクラスを宣言します。
このテスト用構造体を以下の様に使います。 このソースを適当なところで入力し、デバッグモードで1行ずつ実行させると分かりやすいです。
構造体のテストでは、1行目で構造体「ST1」の宣言をしていますが、この時点で「ST1」の実体がメモリに確保されます。 宣言の後で直接「ST1」のメンバ変数「nTest」に1を設定します。
その後で構造体「ST2」の宣言し、「ST2」に「ST1」を代入していますが、 「ST2」に割り当てられた実体に「ST1」の全てがまるまるコピーされます。
「ST2」と「ST1」の実体は全く別の独立したメモリ領域に存在していますので、 「ST2」のメンバ変数「nTest」に2を設定しても、「ST1.nTest」および「ST2.nTest」は異なる値を保持しています。
クラスのテストでは、1行目でクラス「CT1」の宣言をしていますが、この時点ではCT1には実体は設定しておらず、 値的には「Nothing」になっています。尚、値が「Nothing」である参照型の変数のメソッドやプロパティにアクセスしても エラーが発生します。
その後の「New」を行うことで、「ClassTest」の実体がメモリに確保され、その参照が「CT1」に代入されます。 参照とはメモリに確保された「ClassTest」の入れ物を指し示すポインタの様なものです。
この時点で「CT1」のメンバ変数にアクセスが可能になります。
クラスのテストでは、4行目でクラス「CT2」の宣言を行いますが、当然「CT2」の中身は「Nothing」のままです。 ここで5行目で「CT2」に「CT1」の値をコピーしています。 値のコピーと言っても、中身は「ClassTest」の実体メモリへの参照する値です。
(「ClassTest」の入れ物を指し示すポインタのコピー)
最後の行で「CT2」を使って「CT2.nTest」へ2を設定しています。 ここで「CT1」の値をデバッガ等でみますと「2」になっているはずです。 参照型を初めて見る方にとっては、おやと思うでしょうが、 「CT2」も「CT1」もメモリ上の同じ場所を指し示しているので、 「CT1.nTest」で見ても「CT2.nTest」で見ても同じ値になります。
尚、クラス宣言と実体生成を以下の様に記述できます。 「CT2」もNewで生成すれば、全く別のクラス領域を指し示すことになりますので、 「CT1.nTest」と「CT2.nTest」は別の値になります。
■関連記事
⇒VB.NETの関数の参照型データの引数での値渡しと参照渡しの違いについて
⇒VB.NETの関数の戻り値が参照型について
⇒VB.NETの配列のReDimについて
⇒VB.NETの配列は参照型
⇒VB.NETの文字列型(String)について
コメント