【问题标题】:Matlab: Reference to a handle objectMatlab:引用句柄对象
【发布时间】:2016-07-06 20:48:18
【问题描述】:

我能否创建对句柄对象的引用,以便在某一点替换对象本身并更新引用?

例子:

classdef IShifter < handle
  methods (Abstract)
    x = Shift(this, x);
  end
end

classdef Shifter1 < IShifter
  methods
    function x = Shift(this, x)
      x = circshift(x, 1);
    end
  end
end

classdef Shifter2 < IShifter
  methods
    function x = Shift(this, x)
      x = [ 0 ; x ];
    end
  end
end



classdef Item
  properties (Access = 'private')
    shifter; % should be a pointer/reference to the object which is in the respective parent container object
  end

  methods
    function this = Item(shifter)
      this.shifter = shifter;
    end

    function x = test(this, x)
      x = this.shifter.Shift(x);
    end
  end
end

% note this is a value class, NOT a handle class!
classdef ItemContainer
  properties
     shifter;
     items;
  end

  methods
    function this = ItemContainer()
      this.shifter = Shifter1;
      this.items{1} = Item(this.shifter);
      this.items{2} = Item(this.shifter);
    end

    function Test(this)
      this.items{1}.Test( [ 1 2 3] )
      this.items{2}.Test( [ 1 2 3] )
    end
  end
end

那么,输出应该是:

items = ItemContainer();
items.Test();
[ 3 1 2 ]
[ 3 1 2 ]
items.shifter = Shifter2;
items.Test();
[ 0 1 2 ]
[ 0 1 2 ]

但实际上是:

items = ItemContainer();
items.Test();
[ 3 1 2 ]
[ 3 1 2 ]
items.shifter = Shifter2;
items.Test();
[ 3 1 2 ]
[ 3 1 2 ]

因为将新的 Shifter 对象分配给父对象项不会更新容器中的引用。

我正在寻找类似 C 中的所有“移位器”属性都是指针的东西,我可以将任何我想要的移位器对象放入这个“地址”。

ItemContainer 和 Item 不是句柄类。 我想避免使用事件来更新引用或实现 set 方法来更新引用

【问题讨论】:

    标签: matlab pointers reference pass-by-reference


    【解决方案1】:

    Matlab 中的传递引用概念仅此而已(无论如何,主要限于handle-classes)。它没有达到你想要的程度。

    如果您不想使用 set 方法,可以使用返回 {this.shifter,this.shifter} 的 get 方法将 items 设为依赖属性

    根据您的 cmets,items 比单元阵列要复杂一些。因此,您可能希望使用属性itemsStore(或itemsCache,或您喜欢的任何名称来临时存储items)和依赖属性items 来设置您的对象。 items的get方法检查itemsStore是否为空;如果是,则重构项目数组并将其存储在itemsStore 中,如果不是,则仅返回itemStore 的内容。此外,您需要向shifter 添加一个set 方法来清空itemsStore,以便需要重新创建items。请注意,MLint 会给你一个警告,一个属性的 set 方法不应该写入另一个属性。此警告旨在告诉您,当您保存对象然后从磁盘再次加载它时,将执行所有 set 方法。根据执行顺序,写入其他属性的 set 方法可能会产生意想不到的结果。在您的情况下,这没问题,因为清空的 itemStore 是您的代码旨在处理的东西。如果需要,您可以右键单击 MLint 警告,为该行禁用它。

    【讨论】:

    • 这很可悲。但是好的,在最坏的情况下,我可以使用get.shifter(this, shifter) 并更新所有项目。但是:“非依赖属性的设置方法不应访问另一个属性”。我不想让项目依赖,因为这只是一个玩具示例。实际上,我的对象要复杂得多……有什么建议吗?
    • 使用set.shifter 的另一个不合理的问题:Item 的类型为IItem(接口),但并非所有可能的项目都具有shifter 属性。如果对象有,则在构造函数中赋值。因此,set.shifter 方法必须在盲目更新列表中的所有项目对象之前检查类型(或属性是否存在)。不是很优雅:(
    • @divB:我明白了。在这种情况下,项目的 get 方法会更优雅,因为它会根据需要收集所有当前元素。
    • 您能快速详细说明一下吗?您的意思是将items 定义为依赖并在get 方法内的循环中动态创建对象吗?这会奏效。但是,items 会在循环中被非常频繁地访问,并且在每次读取访问时重新创建整个对象层次结构可能非常低效。还是你的意思是别的?
    • @divB:确实,值类使这变得更加复杂。但只有一点:创建一个方法getItems,它返回项目和更新的对象,而不是使用依赖属性。
    【解决方案2】:

    不幸的是,我认为这在 Matlab 中是不可能的。

    但是,当item被定义时,您可以使用set方法或subsasgn重新定义items{1}items{2}的内容。然后你将能够得到你要求的行为。

    最好的,

    【讨论】:

    • 也许我的玩具示例有点误导。我的对象实际上要复杂得多,它不仅仅是静态项目的列表。也许这样理解会更好:ItemContainer 是一个完整的方程层次结构。各个元素是Item。应该使用 IShifter 实例设置(可能的)时间偏移的发生方式(例如零填充、循环偏移)。但是移位器应该设置在方程对象上,而不是内部的单个元素上。有什么建议吗?
    猜你喜欢
    • 2012-05-05
    • 1970-01-01
    • 2011-10-28
    • 2011-09-20
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多