Main Content

ハンドル クラスのコピーの実装

ハンドル クラスの 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);

オブジェクト ab に含まれるハンドル オブジェクトは独立していることを実証します。オブジェクト 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 プロパティ属性を使用して、コピー操作で特定のプロパティ値をコピーしないことを示します。既定では、NonCopyablefalse で、プロパティ値はコピー可能であることを示します。ハンドル クラスのプロパティについてのみ、NonCopyabletrue に設定できます。

matlab.mixin.Copyable から派生されたクラスでは、copyElement の既定の実装は NonCopyable 属性に従います。したがって、プロパティの NonCopyable 属性が true の場合、copyElement はそのプロパティの値をコピーしません。ユーザーのサブクラスで copyElement をオーバーライドすると、NonCopyable 属性の使用方法を選択できます。

属性をコピーしない設定

プロパティ ブロック内で NonCopyabletrue に設定します。

properties (NonCopyable)
   Prop1
end

既定値

コピーできないプロパティがクラス定義で割り当てられた既定値をもつ場合、コピー操作はその既定値をプロパティに割り当てます。たとえば、CopiedClassProp2 に既定値を割り当てます。

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 メソッドを使用して、ab にコピーします。

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);

参考

関連するトピック