ハンドル オブジェクトの動作
複数の変数から同じハンドル オブジェクトを参照することができます。したがって、ユーザーは値クラスのインスタンスとは異なる方法で、ハンドル クラスのインスタンスを操作します。ハンドル オブジェクトの動作を理解すると、ハンドル クラスと値クラスのどちらを実装するかの決定に役立ちます。このトピックでは、そうした操作のいくつかを説明します。
ハンドル クラスの詳細については、ハンドル クラスを参照してください。
ハンドルとは
特定の種類の MATLAB® オブジェクトは "ハンドル" です。変数がハンドルを保持する場合、実際にはオブジェクトへの参照を保持します。
ハンドル オブジェクトを使用すると、複数の変数で同じオブジェクトを参照できるようになります。ハンドル オブジェクトの動作は、ハンドル オブジェクトをコピーしたときや関数に渡したときに何が行われるかに影響します。
ハンドルのコピー
ハンドル オブジェクト変数のコピーはすべて、基となる同じオブジェクトを参照します。この参照の動作は、h
がハンドル オブジェクトを特定する場合、
h2 = h;
が h
と同じオブジェクトを参照する別の変数 h2
を作成するということです。
たとえば、MATLAB の関数 audioplayer
は、特定の音声セグメントを再生するための音源データを含むハンドル オブジェクトを作成します。関数 audioplayer
が返す変数はオーディオ データを表し、これを使用するとオブジェクト関数にアクセスしてオーディオを再生できます。
MATLAB ソフトウェアには、読み込み可能なオーディオ データが用意されており、audioplayer
オブジェクトの作成に使用できます。以下のサンプルはオーディオ データを読み込み、オーディオ プレーヤーを作成してオーディオを再生します。
load gong Fs y gongSound = audioplayer(y,Fs); play(gongSound)
gongSound
オブジェクト ハンドルを別の変数 (gongSound2
) にコピーするとします。
gongSound2 = gongSound;
変数 gongSound
と gongSound2
は同じハンドルのコピーなので、同じ音源を参照します。いずれかの変数を使用して audioplayer
情報にアクセスします。
たとえば、銅鑼 (gong) 音源のサンプル レートを設定するには、SampleRate
プロパティに新しい値を割り当てます。はじめに現在のサンプル レートを取得し、次に新しいサンプル レートを設定します。
sr = gongSound.SampleRate; disp(sr)
8192
gongSound.SampleRate = sr*2;
gongSound2
を使用して同じ音源にアクセスできます。
disp(gongSound2.SampleRate)
16384
新しいサンプル レートで銅鑼の音を再生します。
play(gongSound2)
関数内で変更されるハンドル オブジェクト
引数を関数に渡すと、その関数によって、関数の呼び出し元のワークスペースにある変数が、関数のワークスペースにあるパラメーター変数にコピーされます。
非ハンドル変数を渡しても、呼び出し側のワークスペースにある元の変数に影響が及ぶことはありません。たとえば、myFunc
はローカル変数 var
を変更しますが、関数が終了するとローカル変数 var
は存在しなくなります。
function myFunc(var) var = var + 1; end
変数を定義し、myfunc
に渡します。
x = 12; myFunc(x)
myFunc(x)
を実行しても、x
の値は変化しません。
disp(x)
12
関数 myFunc
は変更後の値を返すことができ、この値は同じ変数名 (x
) または別の変数に割り当てることができます。
function out = myFunc(var) out = var + 1; end
myfunc
で値を変更します。
x = 12; x = myFunc(x); disp(x)
13
引数がハンドル変数の場合、関数はハンドルのみをコピーし、ハンドルによって特定されるオブジェクトはコピーしません。両方のハンドル (元のハンドルとローカル コピー) は同じオブジェクトを参照します。
関数によりオブジェクト ハンドルの参照するデータが変更された場合、その変更内容は、呼び出し元のワークスペースにあるハンドル変数からアクセス可能であり、変更後のオブジェクトを返す必要はありません。
たとえば、関数 modifySampleRate
は audioplayer
のサンプル レートを変更します。
function modifySampleRate(audioObj,sr) audioObj.SampleRate = sr; end
audioplayer
オブジェクトを作成し、関数 modifySampleRate
に渡します。
load gong Fs y gongSound = audioplayer(y,Fs); disp(gongSound.SampleRate)
8192
modifySampleRate(gongSound,16384) disp(gongSound.SampleRate)
16384
関数 modifySampleRate
は変更後の gongSound
オブジェクトを返す必要はありません。これは、audioplayer
オブジェクトがハンドル オブジェクトだからです。
オブジェクトがハンドルかどうかの判定
ハンドル オブジェクトは handle
クラスのメンバーです。このため、関数 isa
を使用して、いつでもオブジェクトをハンドルとして識別できます。関数 isa
はハンドル変数のテストで logical 値 true
(1
) を返します。
load gong Fs y gongSound = audioplayer(y,Fs); isa(gongSound,'handle')
変数が有効なハンドル オブジェクトであるかどうかを判定するには、isa
と isvalid
を使用します。
if isa(gongSound,'handle') && isvalid(gongSound) ... end
削除されたハンドル オブジェクト
ハンドル オブジェクトが削除されていても、そのオブジェクトを参照していたハンドル変数がまだ存在していることがあります。参照先のオブジェクトはもう存在しないため、これらの変数は無効となります。オブジェクトに対して delete
を呼び出すとそのオブジェクトが削除されますが、ハンドル変数は消去されません。
たとえば、audioplayer
オブジェクトを作成するとします。
load gong Fs y gongSound = audioplayer(y,Fs);
出力引数 gongSound
はハンドル変数です。delete
を呼び出すと、オブジェクトと、そこに含まれる音源情報が削除されます。
delete(gongSound)
しかし、ハンドル変数は存在したままです。
disp(gongSound)
handle to deleted audioplayer
whos
コマンドは、gongSound
を audioplayer
オブジェクトとして表示します。
whos
Name Size Bytes Class Attributes Fs 1x1 8 double gongSound 1x1 0 audioplayer y 42028x1 336224 double
メモ
whos
コマンドで返される Bytes の値には、ハンドルによって参照されるデータは含まれていません。これは、多くの変数が同じデータを参照できるからです。
isvalid
ハンドル メソッドが示すように、ハンドル gongSound
は有効なオブジェクトを参照していません。
isvalid(gongSound)
ans = logical 0
削除されたハンドルに対して delete
を呼び出しても何も起こらず、エラーも生じません。有効なハンドルと無効なハンドルの両方を含む配列を delete
に渡すことができます。MATLAB により有効なハンドルは削除されますが、既に無効になっているハンドルの場合にはエラーは発行しません。
無効なハンドル変数のプロパティにアクセスすることはできません。
gongSound.SampleRate
Invalid or deleted object.
オブジェクト プロパティへアクセスする関数およびメソッドはエラーの原因になります。
play(gongSound)
Invalid or deleted object.
変数 gongSound
を削除するには、clear
を使用します。
clear gongSound
whos
Name Size Bytes Class Attributes Fs 1x1 8 double y 42028x1 336224 double