ハンドル クラスのコピーの実装
ハンドル クラスの copy メソッド
ハンドル変数をコピーすると、同じオブジェクトを参照する別のハンドル変数が作成されます。matlab.mixin.Copyable
をサブクラス化して、ハンドル クラスにコピー機能を追加できます。継承された copy
メソッドにより、クラスのオブジェクトのシャロー コピーを作成できます。CopyObj
クラスは、コピー操作の動作を示します。
classdef CopyObj < matlab.mixin.Copyable properties Prop end end
CopyObj
クラスのオブジェクトを作成し、line
オブジェクトのハンドルをプロパティ Prop
に割り当てます。
a = CopyObj; a.Prop = line;
オブジェクトをコピーします。
b = copy(a);
ハンドル変数 a
および b
が異なるオブジェクトを参照していることを確認します。
a == b
ans = logical 0
ただし、a.Prop
によって参照されている line
オブジェクトはコピーされていません。a.Prop
のハンドルは、b.Prop
のハンドルと同じオブジェクトを参照しています。
a.Prop == b.Prop
ans = logical 1
コピー操作の動作の詳細については、copy
を参照してください。
コピー操作のカスタマイズ
matlab.mixin.Copyable
からクラスを派生させ、ハンドル オブジェクトのコピー動作をカスタマイズします。matlab.mixin.Copyable
クラスはハンドル クラスから派生した抽象基底クラスです。matlab.mixin.Copyable
は、以下を定義することでオブジェクトのコピー操作をカスタマイズするためのテンプレートを提供しています。
copy
— オブジェクトをコピーするインターフェイスを定義する、シールされたメソッドcopyElement
— オブジェクトのコピー操作をサブクラス用にカスタマイズするため、サブクラスがオーバーライドできる保護されたメソッド
matlab.mixin.Copyable
copy
メソッドは copyElement
メソッドを呼び出します。ユーザーのサブクラスは、copyElement
のそれ自身のバージョンを定義してコピー操作をカスタマイズします。
copyElement
の既定の実装では、すべての非依存プロパティのシャロー コピーが作成されます。copyElement
は各プロパティ値をコピーし、それを新しい (コピーされた) プロパティに代入します。プロパティ値がハンドル オブジェクトの場合、copyElement
はハンドルはコピーしますが基となるデータはコピーしません。
プロパティごとに異なるコピー動作を実装するために、copyElement
をオーバーライドします。たとえば、SpecializedCopy
クラスの copyElement
メソッドの場合は以下のとおりです。
新しいクラス オブジェクトを作成
Prop1
の値を新しいオブジェクトへコピーコピーが作成されたときのタイムスタンプを追加して
Prop2
の既定値を再初期化
classdef SpecializedCopy < matlab.mixin.Copyable properties Prop1 Prop2 = datestr(now) end methods(Access = protected) function cp = copyElement(obj) cp = SpecializedCopy; cp.Prop1 = obj.Prop1; cp.Prop2 = datestr(now); end end end
このクラスのオブジェクトを作成し、Prop1
に値を代入します。
a = SpecializedCopy; a.Prop1 = 7
a = SpecializedCopy with properties: Prop1: 7 Prop2: '17-Feb-2015 17:51:23'
継承された copy
メソッドを使用して a
のコピーを作成します。
b = copy(a)
b = SpecializedCopy with properties: Prop1: 7 Prop2: '17-Feb-2015 17:51:58'
コピー (オブジェクト b
) は Prop1
と同じ値をもちますが、サブクラスの copyElement
メソッドが新しい値を Prop2
に代入しています。異なるタイムスタンプに注目してください。
ハンドルを含むプロパティのコピー
オブジェクトをコピーすると、オブジェクト プロパティの値もコピーされます。オブジェクト プロパティには、ハンドル オブジェクトを含む、他のオブジェクトを含めることができます。ハンドル オブジェクトを含むプロパティの値を単にコピーする場合、実際にはオブジェクト自体ではなくハンドルをコピーすることになります。したがって、そのコピーは元のオブジェクトと同じオブジェクトを参照します。matlab.mixin.Copyable
クラスから派生したクラスでは、コピー メソッドがクラスのオブジェクトをコピーする方法をカスタマイズできます。
ハンドル コピーをサポートするクラス
オブジェクト プロパティにハンドルを保存するクラスを定義するとします。クラスのオブジェクトをコピーできるようにし、オブジェクトの各コピーが新しいハンドル オブジェクトを参照するようにするとします。次の手順を使用してクラスのコピー動作をカスタマイズします。
matlab.mixin.Copyable
のサブクラスを作成します。copyElement
をオーバーライドして、ハンドルを含むプロパティをコピーする方法を制御します。プロパティ値はハンドルなので、同じクラスの新しい既定オブジェクトを作成します。
プロパティ値を、元のハンドル オブジェクトから新しいハンドル オブジェクトにコピーします。
HandleCopyクラスは、ハンドル オブジェクトを含むプロパティのコピー操作をカスタマイズします。ColorPropクラスは、Prop2
に割り当てるハンドル オブジェクトを定義します。
オブジェクトを作成してプロパティ値を代入します。
a = HandleCopy; a.Prop1 = 7; a.Prop2 = ColorProp;
matlab.mixin.Copyable
から継承した copy
メソッドを使用してオブジェクトのコピーを作成します。
b = copy(a);
オブジェクト a
と b
に含まれるハンドル オブジェクトは独立していることを実証します。オブジェクト a
の値を変更しても、オブジェクト b
には影響しません。
a.Prop2.Color = 'red'; b.Prop2.Color
ans = blue
HandleCopy
HandleCopy
クラスは、このクラスのオブジェクトのコピー操作をカスタマイズします。
classdef HandleCopy < matlab.mixin.Copyable properties Prop1 % Shallow copy Prop2 % Handle copy end methods (Access = protected) function cp = copyElement(obj) % Shallow copy object cp = copyElement@matlab.mixin.Copyable(obj); % Get handle from Prop2 hobj = obj.Prop2; % Create default object new_hobj = eval(class(hobj)); % Add public property values from orig object HandleCopy.propValues(new_hobj,hobj); % Assign the new object to property cp.Prop2 = new_hobj; end end methods (Static) function propValues(newObj,orgObj) pl = properties(orgObj); for k = 1:length(pl) if isprop(newObj,pl{k}) newObj.(pl{k}) = orgObj.(pl{k}); end end end end end
ColorProp
ColorProp
クラスは、その Color
プロパティに RGB 値を代入することで色を定義します。
classdef ColorProp < handle properties Color = 'blue'; end end
コピーのプロパティの排除
NonCopyable
プロパティ属性を使用して、コピー操作で特定のプロパティ値をコピーしないことを示します。既定では、NonCopyable
は false
で、プロパティ値はコピー可能であることを示します。ハンドル クラスのプロパティについてのみ、NonCopyable
を true
に設定できます。
matlab.mixin.Copyable
から派生されたクラスでは、copyElement
の既定の実装は NonCopyable
属性に従います。したがって、プロパティの NonCopyable
属性が true
の場合、copyElement
はそのプロパティの値をコピーしません。ユーザーのサブクラスで copyElement
をオーバーライドすると、NonCopyable
属性の使用方法を選択できます。
属性をコピーしない設定
プロパティ ブロック内で NonCopyable
を true
に設定します。
properties (NonCopyable) Prop1 end
既定値
コピーできないプロパティがクラス定義で割り当てられた既定値をもつ場合、コピー操作はその既定値をプロパティに割り当てます。たとえば、CopiedClass
は Prop2
に既定値を割り当てます。
classdef CopiedClass < matlab.mixin.Copyable properties (NonCopyable) Prop1 Prop2 = datestr(now) % Assign current time end end
コピーするオブジェクトを作成し、Prop1
に値を割り当てます。
a = CopiedClass; a.Prop1 = 7
a = CopiedClass with properties: Prop1: 7 Prop2: '17-Feb-2015 15:19:34'
matlab.mixin.Copyable
から継承した copy
メソッドを使用して、a
を b
にコピーします。
b = copy(a)
b = CopiedClass with properties: Prop1: [] Prop2: '17-Feb-2015 15:19:34'
b
のコピーには、Prop1
の値はコピーされていません。Prop2
の値は、その既定値に設定されています。これは、MATLAB® がクラスを最初に読み込んだ時に決定した値です。タイムスタンプは変わりません。
動的なプロパティをもつオブジェクト
dynamicprops
クラスのサブクラスにより、クラスのオブジェクトにプロパティを追加できます。dynamicprops
から派生したクラスが matlab.mixin.Copyable
のサブクラスでもある場合、copyElement
の既定の実装では動的プロパティをコピーしません。動的プロパティの NonCopyable
の既定値は true
です。
copyElement
の既定の実装は、動的プロパティの NonCopyable
属性に従います。動的プロパティのコピーを許可する場合は、NonCopyable
属性を false
に設定します。動的プロパティをコピーすると、プロパティ値とプロパティ属性の値がコピーされます。
たとえば、次のコピー操作は動的プロパティ DynoProp
をコピーします。これは、NonCopyable
属性が false
に設定されているためです。オブジェクト obj
は、dynamicprops
および matlab.mixin.Copyable
の両方から派生したクラスのインスタンスでなければなりません。
obj = MyDynamicClass; p = addprop(obj,'DynoProp'); p.NonCopyable = false; obj2 = copy(obj);