ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

オブジェクト配列のインデックス付け

既定のインデックス付きの参照と代入

MATLAB® クラスは既定でオブジェクト配列のインデックスをサポートしています。多くのクラス設計では、この動作に変更を加える必要はありません。

配列では、添字表記を使用して配列の要素を参照し代入することが可能です。この表記は特定の配列要素のインデックスを指定します。たとえば、関数 randi の使用と連結によって、数値配列を 2 つ作成するものとします。

1 から 9 までの整数からなる 3 行 4 列の配列を作成します。

A = randi(9,3,4)
A =

     4     8     5     7
     4     2     6     3
     7     5     7     7

3、6、9 の数値からなる 1 行 3 列の配列を作成します。

B = [3 6 9];

インデックス値をかっこ内で使用して 2 つの配列の要素を参照し、代入します。

B(2) = A(3,4);
B
B =
     3     7     9

インデックス付きの参照を含むステートメントを実行すると、

C = A(3,4);

MATLAB は組み込みの関数 subsref を呼び出し、ステートメントをどのように解釈するか決めます。同様に、インデックス付き代入を含むステートメントを実行すると、

C(4) = 7;

MATLAB は組み込み関数 subsasgn を呼び出し、ステートメントをどのように解釈するか決めます。

MATLAB の関数 subsrefsubsasgn は、既定ではユーザー定義オブジェクトと共に動作します。たとえば、同じクラスに属するオブジェクトの配列を作成します。

for k=1:3
   objArray(k) = MyClass;
end

オブジェクト配列 objArray の 2 つ目の要素を参照すると、k = 2 のときに作成されるオブジェクトを返します。

D = objArray(2);
class(D)
ans =

MyClass

同じクラスに属するオブジェクトの配列、または初期化されていない変数にオブジェクトを割り当てることができます。

newArray(3,4) = D;

オブジェクトの配列は、MATLAB の数値配列のような機能をもちます。ユーザー クラスで標準的な配列の動作を提供するために特別なメソッドを実装する必要はありません。

配列のインデックスに関する一般的な情報は、「行列のインデックス」を参照してください。

変更できること

subsrefsubsasgn というクラス メソッドを実装することで、ユーザー クラスのインデックス付きの参照や代入の動作を変更できます。構文の説明として、それぞれのリファレンス ページを参照してください。

いったん subsref または subsasgn メソッドをユーザー クラスに追加すると、MATLAB はクラス メソッドのみを呼び出し、組み込み関数は呼び出しません。したがって、ユーザー クラスでサポートしようとする、インデックス付きの参照と代入の操作すべてを、ユーザー クラス メソッドで実装しなければなりません。こうした操作には、次が含まれます。

  • クラス メソッドに対するドット表記の呼び出し

  • プロパティを含むドット表記の参照と代入

  • かっこ '()' を使用するインデックス

  • 中かっこ '{}' を使用するインデックス

subsref メソッドや subsasgn メソッドを実装することにより、ユーザー クラスのオブジェクトに対するインデックス式の解釈を完全に制御できるようになります。MATLAB により既定で提供される各種動作を実装することは重要です。

インデックス機能を変更する場合

既定であるオブジェクト配列のインデックスと、プロパティおよびメソッドにアクセスするためのドット表記は、ユーザー定義のオブジェクトが組み込みクラスと同様に動作することを可能にします。たとえば、数値データの配列を含む Data というプロパティをもつクラスを定義するものとします。

次のステートメント

obj.Data(2,3)

は、配列の第 2 行第 3 列に含まれる値を返します。オブジェクトの配列では、次のような式を使用します。

objArray(3).Data(2,3)

このステートメントは配列の 3 番目の要素の第 2 行第 3 列に含まれる値を返します。

ユーザー クラス設計において、MATLAB の既定の動作と異なる動作が必要になる場合、既定のインデックスの動作を変更してください。

メソッドで呼び出される組み込みの subsref および subsasgn

MATLAB は、オーバーロード メソッド内ではクラス定義の subsref メソッドや subsasgn メソッドを呼び出しません。クラス メソッド内において、MATLAB は必ず組み込みの関数 subsref および subsasgn を呼び出します。この動作はクラス定義の subsref および subsasgn メソッド内でも行われます。

たとえば、クラス メソッド内で、以下のドット参照を実行します。

obj.Prop

このドット参照は、組み込み関数 subsref を呼び出します。クラス定義された subsref メソッドを呼び出すには、以下を使用します。

subsref(obj,substruct('.','Prop'))

メソッドでクラス定義の subsref または subsasgn メソッドの機能が必要になった場合、クラスはオーバーロードしたメソッドを関数として呼び出さなければなりません。演算子 '()''{}''.' は使用しないでください。

たとえば、多項式を表すクラスを定義するとします。このクラスには、添字と等しい独立変数の値で多項式を評価する subsref メソッドがあります。次のステートメントで、多項式をその係数と共に定義するとします。

p = polynom([1 0 -2 -5]);

結果の多項式に対する MATLAB 式は次のようになります。

x^3 - 2*x - 5

次の添字付きの式は、x = 3 における多項式の値を返します。

p(3)
ans =
    16

他のクラス メソッドでこの機能を使用するものとします。そのために、関数 subsref を直接呼び出してください。evalEqual メソッドは、2 つの polynom オブジェクトと評価する点での多項式の値を受け入れます。

methods
   function ToF = evalEqual(p1,p2,x)
      % Create arguments for subsref
      subs.type = '()';
      subs.subs = {x};
      % Need to call subsref explicitly 
      y1 = subsref(p1,subs);
      y2 = subsref(p2,subs);
      if y1 == y2
         ToF = true;
      else 
         ToF = false;
      end
   end
end

この動作により、特化した動作を実装する、MATLAB の標準のインデックス付けが使用できます。組み込みインデックスとクラスで変更したインデックスの使い方の例は、変更されたインデックスをもつクラスを参照してください。

Access 属性のオーバーライドの回避

subsref はクラス メソッドなので、プライベートなクラス メンバーへのアクセスをもちます。さまざまなタイプの参照を取り扱うときには、プライベート メソッドやプライベート プロパティに不注意でアクセスすることは避けてください。プライベート プロパティ xy をもつクラスに対して定義されたこの subsref メソッドを考えます。

classdef MyPlot
   properties (Access = private)
      x
      y
   end
   properties
      Maximum
      Minimum
      Average
   end
   methods
      function obj = MyPlot(x,y)
         obj.x = x;
         obj.y = y;
         obj.Maximum = max(y);
         obj.Minimum = min(y);
         obj.Average = mean(y);
      end
      function B = subsref(A,S)
         switch S(1).type
            case '.'
               switch S(1).subs
                  case 'plot'
                     % Reference to A.x and A.y call built-in subsref
                     B = plot(A.x,A.y);
                  otherwise
                     % Enable dot notation for all properties and methods
                     B = A.(S.subs);
               end
         end
      end
   end
end

この subsref によりドット表記の使用が可能になり、名前 'plot' を使用してプロットを作成できます。次のステートメント

obj = MyPlot(1:10,1:10);
h = obj.plot;

は、関数 plot を呼び出し、graphics オブジェクトへのハンドルを返します。

各メソッドとプロパティ名を明示的にコード化する必要はありません。内側の switch ブロックの otherwise コードが、case ステートメントで明示的に指定しない名前参照を管理します。ただし、この手法を使用すると、プライベートなまたは保護されたクラスのメンバーがドット表記で参照可能になります。たとえば、以下のステートメントで、プライベート プロパティ x を参照することができます。

obj.x
ans =

     1     2     3     4     5     6     7     8     9    10

同じことがプライベートまたは保護されたプロパティへの代入を可能にする、subsasgn メソッドの記述にもあてはまります。subsrefsubsasgn メソッドは、クラス設計に違反しないように、特定のプロパティとメソッドの名前をそれぞれ明示的にコード化する必要があります。

関連する例

この情報は役に立ちましたか?