2016-02-05 7 views
6

コンストラクタ内のオブジェクトに不変のUUIDを割り当てるクラスがあります。以下は、簡略図である。MATLABデフォルトの配列要素を代入するときにコンストラクタメソッドを呼び出すようにします

classdef mytest  
    properties (GetAccess = public, SetAccess = immutable)   
     uuid   
    end  
    properties 
     val 
    end 
    methods   
     function obj = mytest(valIn) 
      obj.uuid = char(java.util.UUID.randomUUID.toString); 
      if nargin < 1 
       valIn = 0; 
      end 
      obj.val = valIn; 
     end 
    end 
end 

これは、一般的に大きな取り組んでいるが、配列にデフォルトの要素を割り当てるときに私はMATLABの行動の問題を発見しました。配列の4にデフォルトの要素1を埋めるために、入力引数なしで4回、一度入力引数2で割り当てるために - 私は

>> a(5) = mytest(2); 

を入力した場合、コンストラクタは5回呼び出されることを想定していました最終要素。

しかし、これはMATLABの機能ではなく、コンストラクタを入力なしで1回だけ呼び出し、次に結果を4回コピーして要素1〜4を埋め込みます。これはつまりUUIDがEF要素1の端まで同じ4:それは私がちょうど期待していなかったこの文書化された行動が判明し、私は一種のMathWorks社はそれを行うことを選択した理由を理解

>> {a.uuid}' 
ans = 
    '4424b91b-0977-4b4c-b18b-c4564875b952' 
    '4424b91b-0977-4b4c-b18b-c4564875b952' 
    '4424b91b-0977-4b4c-b18b-c4564875b952' 
    '4424b91b-0977-4b4c-b18b-c4564875b952' 
    'dbb8d862-8a1c-4bf9-876f-ef786e11a896' 

(別々に何度も何も入力しないコンストラクタを呼び出すオーバーヘッドを望んでいないかもしれません)。

しかし、私はこのクラスに必要な動作ではありません - 誰もが、各要素に対してコンストラクタを強制的に呼び出す方法を知っていますか?あるいは、あなたは望む振る舞いを持つ別のクラスデザインを提案することができますか?その場合にはmatlab.mixin.Copyableから私のクラスを継承し、copyElementの振る舞いが役立つかもしれないオーバーライド - - MATLABはcopyメソッドを使用して、これらのデフォルトの要素をコピーするかどうか、私が調べた

PSが、それはそれのように見えるが、それはコピーを行う方法はありません:(

+0

以前に未定義の変数に '(5)'呼び出すと、あなたが呼んでいるものとのみ5番目の要素を埋めるためにしようとすると、残りは0でなければならないことの問題ではありません - しかし、あなたのケースでは、空きのあなたのクラスの可能なインスタンス?最初の4つの値を何かに設定して、 'a(1:5)= mytest(2);'(おそらくスカラー展開のために動作しません)か、同じループで同じことを試みましたか? –

+0

@AndrasDeakいいえ、それは問題ではありません。 'a'の最初の4つの値はすべて、' 0'という 'val'プロパティを持っています。それは、入力引数なしでコンストラクタが呼び出されるので、期待どおりのものです。問題は、コンストラクタがそれぞれ別々に呼び出されなかったので、 'a'の最初の4つの値はすべて同じUUIDを持つということです。 –

+0

私はそれを理解しました。しかし、あなたが 'a(1:4)= mytest();を最初に、または' k = 1:4、a(k)= mytest(); 'と呼ぶと、それは違いを生みますか?最初の人は助けにならないと思っています.2番目の人は助けてもらえますが、なぜ2番目の人をやりたくないのか分かります。 [ランダムに初期化されたドキュメントの例](http://www.mathworks.com/help/matlab/matlab_oop/creating-object-arrays.html#buod76n-1)は、配列をループします。 –

答えて

2

免責事項:私はMATLABクラスとあまり慣れていないんだ

the relevant docsを見てみると、あなたが右のすべてをやっているようだ、とそうMATLABは、次のとおりです。

a(1,7) = SimpleValue(7)

配列要素a(1,7)に割り当てられたオブジェクトがプロパティに割り当てられる値として、コンストラクタに渡される入力引数を使用する:

...

MATLAB無しでa(1,1:6)要素に含まれるオブジェクトを作成しません入力引数。プロパティーのデフォルト値は空です[]

...

MATLABは、配列の各要素に返されたオブジェクトに一度コピーSimpleValueコンストラクタを呼び出します。

これは何を経験していることは、文書の行動であることを示唆している。以前に割り当てられていない配列要素の自動割り当ては、ゼロ入力引数を持つコンストラクタへ単一の呼び出しで行われます。

これはランダムな初期化を使用してanother exampleと一致しても:サンプルコードは、異なるランダムなデータを含むように、アレイの5つの要素を設定する

for k = 1:5 
    a(k) = ObjProp; 
end 

を使用します。ドキュメントから少なくとも、これはあなたの問題の回避策であるように思われます。手で空の要素を初期化します(これはおそらくあなたがやりたいことではありません)。

+0

Andreasありがとうございますが、これは質問に答えることはできません - 手で要素を個別に初期化することは問題ありません。しかし、私はクラスを共有し、ユーザーがそれを確実に行うことはできません。私はクラスの振る舞いを制御する方法を探しているので、そうしないと正しいことができます。 –

+0

@SamRobertsありがとう、私も上記のあなたのコメントを読んだ。私はそれを答えとして意味しています。少なくともドキュメンテーションから、 "あなたはそれをすることはできません"と答えています。私はこれをここに残し、MATLAB-OOPに精通した方が来て、間違っていることを願っています:)しかし、MATLABでは、自動初期化のためにコンストラクタを一度だけ呼び出すようになっています。 –

+0

問題はありません。あなたの答えをここに保持してください。「あなたができない」のように見えますが、それは答えかもしれません。私の唯一の考えは現在、複雑な方法で 'subsasgn'をオーバーロードすることができるかもしれないということです。それで、まだ存在しない要素に代入するかどうかを検出し、新しい要素ごとにコンストラクタを個別に呼び出し、実際の割り当てを行います。しかし、それは非常に難しく、エラーを起こしやすいようです。 –

関連する問題