3-2 値型と参照型
3-2-1 2 種類のデータ型
3-1-3 「VB .NET でのデータ型」で触れたように、予約されたデータ型がいくつかあります。このデータ型は、大きく 2 種類に分類することができます。それが、「値型(Value type)」 と 「参照型(Reference Type)」 です。この 2 種類は、データのメモリ確保の方法が異なります。
変数などでデータを扱う際には、そのデータ型が 「値型」 であるか、「参照型」 であるかを意識する必要があります。この分類は、各データ型によって固定です。例えば、「Integer 型」 の変数は常に値型です。また、「String 型」 の変数では、その変数は常に 「参照型」 です。
[例] 値型と参照型
1: Dim X As Integer '値型の変数
2: Dim S As String '参照型の変数
これを、前述のデータ型一覧表をもとに分類すると、以下のようになります。String 型と Object 型が参照型であり、その他のデータは値型です(表 3-3)。
型 (タイプ) | 型の分類 |
---|---|
Byte | 値型 |
Short | |
Integer | |
Long | |
Single | |
Double | |
Decimal | 値型 |
Char | |
String | 参照型 |
Boolean | 値型 |
Date | |
Object | 参照型 |
表 3-3 値型と参照型
型 (タイプ) | 型の分類 |
---|---|
Decimal | 値型 |
Char | |
String | 参照型 |
Boolean | 値型 |
Date | |
Object | 参照型 |
表 3-3 値型と参照型(2)
このあとは、「値型」 と 「参照型」 がそれぞれどのようなものかを説明します。
3-2-2 値型とは?
値型データの変数を宣言した場合、その型のデータ領域自体がメモリ上に確保されることを意味します。例えば、Integer 型の変数 X をローカル変数として宣言すれば、Integer 型は値型で 4 バイト長であるので、この変数 X のために 4 バイトの領域が確保されます。また、Long 型の変数 Y を宣言すれば、Long 型は 8 バイトであることから、この変数 Y のために 8 バイトの領域が確保されます。
以下の例は、この変数宣言をおこなっている例です(WinApp2 プロジェクトの Button1_Click イベントハンドラに記述した場合)。
[例] 値型である Integer 型、Long 型の変数領域を確保
1: Private Sub Button1_Click( ByVal sender As System.Object, ...
2: Dim X As Integer '4 バイトの領域確保
3: Dim Y As Long '8 バイトの領域確保
4: End Sub
なお、この例で変数 X と変数 Y は、メソッド内の(Static ではない)ローカル変数なので、メソッドの開始とともに変数 X と変数 Y の相応の領域が確保され、メソッドの終了とともに、変数は解放されます。
この値型のデータの扱いは、特に難しくはないと思います。少々わかりづらいのが、次項で説明する参照型です。
3-2-3 参照型とは?
参照型のデータでは値型とは異なり、その変数を宣言したからといって、そのデータ型にみあう領域が確保される訳ではありません。
VB .NET で予約されたデータ型のうち、参照型は 「Object 型」 と 「String 型」 です。この 2 つの型については、以下のように変数を宣言しても、その型にみあう大きさのデータ領域がすぐに確保される訳ではありません(Object 型を理解するには、第 5 章 「クラスの定義と実装」 のクラスとクラス派生の概念が必要なので、ここでは省略します)。
[例] 参照型である Object 型、String 型の変数宣言
1: Private Sub Button1_Click( ByVal sender As System.Object, ...
2: Dim Ob As Object 'データ領域はまだ確保されない
3: Dim S As String 'データ領域はまだ確保されない
4: End Sub
このプログラムにあるように、変数 X と変数 Y をローカル変数として宣言した場合、メモリ上に確保されるのは、その型のデータ実体ではなく、データ実体のメモリ上の位置情報を格納する領域です。メモリ上の位置情報とは、データ実体がメモリ上のどこに存在するか特定するための情報です。この位置情報のことを、「参照情報」 ともいいます。この参照情報の正確なフォーマットは、意識する必要はありません。しかし、メモリ上の位置を特定するためには、参照情報として、メモリ番地(メモリアドレス)などを利用していると考えられます。
以下のように String 型変数 S に文字列データを代入する場合、感覚的には、変数 S に文字列データが代入されるようにみえます。しかし厳密には、ダブルコーテーションで囲まれたデータが、CLR(Common Language Runtime)によってメモリ領域に確保されており、その文字列データが存在する位置情報が、変数 S に代入されています。このような状態を
「変数 S は、文字列 "hello,world!" を参照している。」
と表現します。変数 S に代入されるのは、文字列データの実体ではなく、文字列データを参照するための位置情報です。
[例] 参照情報を変数 S に設定する
Dim S As String
S = "hello,world!"
この例をみる限り、値型と参照型の違いはあまりみえないかもしれません。しかし、この値型と参照型の違いは、変数の操作などさまざまなデータの扱い方に大きく影響してきます。これ以降の説明の中でも必要に応じて、値型と参照型の違いについて何回か取り上げます。
この項では、値型と参照型の基本的な性質の違いを理解するまでにとどめておきます。値型と参照型でのデータの格納の様子を比較してみると、以下のようになります(図 3-8)。
図 3-8 値型変数と参照型変数の値の格納
この例でもわかるように、参照型の変数 S 自体は、String 型のデータ実体ではないことがわかります。それでは、参照型データの実体はどのように確保されるのでしょうか?
文字列定数の場合は、上記の例のように二重引用符(ダブルコーテーション)を使った文字列データを表記するだけで、String 型データが確保されます。文字列に関しては、書き方はそれほど難しくありません。それ以外の参照型データでは、New キーワードを使って、明示的にデータ領域を確保します。New キーワードについては、このあとの配列の説明と第 5 章 「クラスの定義と実装」 で登場します。
ワンポイント |
---|
● for VB6Visual Basic でいえば、参照型のデータは Object 型や任意の COM オブジェクトのデータ型です。以下のように変数が宣言されている場合、1 行目の変数 X が値型なので、Integer 型データが格納される領域を確保しますが、2 行目や 3 行目の変数宣言だけでは、「Object」 型や 「Excel.Application」 型のデータ実体は存在しません。実体を生成するためには、4 行目にあるように、New キーワードなどで明示的につくる必要があります。Visual Basic 6.0 の Set ステートメントは、参照情報を変数に設定する機能があります。 [例] Visual Basic の変数宣言
なお、Visual Basic では、参照情報の代入には Set を使い、通常の値の代入には単に 「=」 演算子だけ(または Let)を使うというように、使い分けがありましたが、VB .NET では、値型の代入も参照型の代入も 「=」 演算子を使います。VB .NET において、参照情報の代入をおこなう Set ステートメントはありません。 |