ハンドル クラスのコピーの実装
ハンドル クラスの 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);