2017-10-23 3 views
3

私はMatlabをかなり新しくしています。「一方向のハンドルクラス」を作成する方法があるかどうか疑問に思っていました。Matlabハンドルクラス内に「一方向依存」を作成する方法

良く説明するために、私はTEST_2(子)に影響を与えるためにTEST_1(親)内のプロパティに適用された変更を望んでいたのプロパティ「PROP1」と「PROP2」

test_1 = test_class(5,10) 
test_2 = test_1 

とはtest_classと呼ばれるクラスを、持って言うことができますが、私はそう

test_1.prop1 = 20; 
test_2.prop1: 20 

test_2.prop2 = 30; 
test_1.prop2: 5 

は、このような「一方通行dependecy」を作成する方法はあり、TEST_2の変化がTEST_1に影響を与えるためにしたくないですか?

ありがとうございます!

答えて

3

これは、プロパティセットリスナーを活用することで、サブサグの問題に陥ることなく実行できます。この方法では、子供のコピーを保持して管理する必要はありません。

classdef test_class < matlab.mixin.Copyable 

    properties(SetObservable) 
     prop1 
     prop2 
    end 

    properties 
     prop3 
    end 

    methods 
     function obj = test_class(in1, in2, in3) 
      obj.prop1 = in1; 
      obj.prop2 = in2; 
      obj.prop3 = in3; 
     end 
     function ref = make_dependent_reference(obj) 
      ref = copy(obj); 

      cls = metaclass(obj); 
      observableProps = cls.PropertyList.findobj('SetObservable',true); 
      for ct =1:numel(observableProps) 
       obj.addlistener(observableProps(ct).Name, 'PostSet', ... 
        @(prop,evd)ref.update_dependent_reference(prop,evd)); 
      end 
     end 
    end 
    methods(Access=private) 
     function update_dependent_reference(ref, prop, evd) 
      ref.(prop.Name) = evd.AffectedObject.(prop.Name); 
     end 
    end 
end 

注、これはあなたがこれらのプロパティへの参照の更新は私が上に示されているようSetObservableないプロパティを無視することを選択することも、SetObservableするプロパティが必要です。これは、次のようになりますfindobjコールを使用するか、代わりにすべてのプロパティを操作して、SetObservable以外のプロパティに対してaddlistenerがエラーを呼び出せるようにすることができます。

>> t = test_class(5,10,15) 

t = 

    test_class with properties: 

    prop1: 5 
    prop2: 10 
    prop3: 15 

>> ref = t.make_dependent_reference 

ref = 

    test_class with properties: 

    prop1: 5 
    prop2: 10 
    prop3: 15 

>> ref.prop1 = 6 

ref = 

    test_class with properties: 

    prop1: 6 
    prop2: 10 
    prop3: 15 

>> t 

t = 

    test_class with properties: 

    prop1: 5 
    prop2: 10 
    prop3: 15 

>> t.prop2 = 11 

t = 

    test_class with properties: 

    prop1: 5 
    prop2: 11 
    prop3: 15 

>> ref 

ref = 

    test_class with properties: 

    prop1: 6 
    prop2: 11 
    prop3: 15 
+0

とてもエレガントです! – rahnema1

0

私はこれが可能ではないと思います。同じ基本オブジェクト(2方向依存)を参照するハンドルオブジェクトのコピー、またはコピーが互いに独立している値オブジェクトのいずれかを持つことができます。 Object behavior.

あなたはハンドルを含みPropertyを持つ値オブジェクトを作成することができるかもしれません...ので、あなたのオブジェクトの一部は、2ウェイおよび部分が1方向です。しかし、それはあなたが求めているものではありません。

3

これは基本的な実装です。各オブジェクトには親と子の配列があります。 subsasgnを使用すると、オブジェクトとその子のプロパティを変更することができます。また、オブジェクトは一方向であるため、親のプロパティを変更したくないためです。

使用方法:我々はa.prop1 = 7;を設定した場合

a = oneway(1,2); 
b = oneway(a); 
c = oneway(b); 

が、その後bcの変化につながるものに変更されます。直接の子のみを変更したい場合は、行31とコメント行30のコメントを外すことができます。

classdef oneway < handle 
    properties 
     parent 
     children={}; 
    end 
    properties 
    prop1 
    prop2 
    end 
    methods 
     function obj = oneway(varargin) 
      if nargin == 1 
       a = varargin{1}; 
       if isa(a,'oneway') 
        obj.prop1 = a.prop1; 
        obj.prop2 = a.prop2; 
        obj.parent = a; 
        a.children{end+1} = obj; 
       end 
      elseif nargin == 2 
       obj.prop1 = varargin{1}; 
       obj.prop2 = varargin{2}; 
      end 
     end 
     function obj = subsasgn(self, S, B) 
      if strcmp(S.type, '.') 
       if ismember(S.subs, properties(self)) 
        obj = builtin('subsasgn', self, S, B); 
        for k = 1: numel(self.children) 
         self.children{k} = subsasgn(self.children{k},S,B); 
         %self.children{k} = builtin('subsasgn', self.children{k}, S, B); 
        end 
       end 
      end 
     end 
     function delete(self) 
      self.parent.children (cellfun(@(x)x==self,self.parent.children))=[]; 
      for k = 1: numel(self.children) 
       self.children{k}.parent =[]; 
      end 
     end 
    end 
end 
+0

これはまさに私が必要としていたもので、魅力的なものです!どうもありがとうございます!!! –

関連する問題