【问题标题】:Matlab proxy class issue. (re: dependent properties)Matlab 代理类问题。 (重新:依赖属性)
【发布时间】:2011-07-07 16:13:30
【问题描述】:

考虑以下 Matlab (2009a) 类:

classdef BigDeal < handle
    properties
        hugeness = magic(2000);
    end
    methods
        function self = BigDeal()
        end
    end
end


classdef BigProxy < handle
    properties(Dependent)
        hugeness
    end
    properties(Access = private)
        bigDeal
    end
    methods
        function self = BigProxy(bigDeal)
            self.bigDeal = bigDeal;
        end
        function value = get.hugeness(self)
            value = self.bigDeal.hugeness;
        end
    end
end

现在考虑它们的以下用途:

设置:

>> b = BigDeal

b = 

  BigDeal handle

  Properties:
    hugeness: [10x10 double]

  Methods, Events, Superclasses

单层:

>> pb = BigProxy(b)

pb = 

  BigProxy handle

  Properties:
    hugeness: [10x10 double]

  Methods, Events, Superclasses

双层:

>> ppb = BigProxy(pb)

ppb = 

  BigProxy handle with no properties.
  Methods, Events, Superclasses

问题: 为什么我的双层代理看不到hugeness 而单层代理可以看到?可以计算相关属性 - 但由于某种原因,这是否只深入一层?


更新:请参阅下面的解决方法。

【问题讨论】:

    标签: oop class matlab proxy


    【解决方案1】:

    这里的问题有两个:

    1. BigProxy 对象构造函数旨在接受具有(非依赖)hugeness 属性(如BigDeal 对象)的输入对象,然后BigProxy 对象可以访问该属性计算它自己的依赖 hugeness 属性的值。

    2. 当您创建ppb 时,您将BigProxy 对象传递给BigProxy 构造函数,并且您显然无法从另一个依赖属性计算依赖属性。例如,这是我尝试访问ppb.hugeness时抛出的错误:

      ??? In class 'BigProxy', the get method for Dependent property 'hugeness'
      attempts to access the stored property value.  Dependent properties don't
      store a value and can't be accessed from their get method.
      

      换句话说,外部BigProxy 对象尝试通过访问内部hugeness 的存储值来计算其依赖的hugeness 属性的值BigProxy@ 对象,但没有存储值,因为它是dependent property

    我认为解决这种情况的方法是让BigProxy 构造函数检查其输入参数的类型,以确保它是BigDeal 对象,否则抛出错误。

    【讨论】:

    • 我想我同意你的分析......虽然我觉得很烦人应该人为地阻止我创建代理到代理。
    • 这让人想起 Matlab 如何不会从其他类方法中调用重载的 subsref 方法。我想,这似乎是出于类似原因的类似限制。
    【解决方案2】:

    Gnovice 很好地回答了“为什么”这个问题,因此我授予他荣耀的绿色支票。但是,对于那些想要解决问题的人,您可以执行以下操作:

    classdef BigDeal < handle
        properties
            hugeness = magic(10000);
        end
        methods
            function self = BigDeal()
            end
        end
    end
    
    
    classdef BigProxy < handle
        properties(Dependent)
            hugeness
        end
        properties(Access = private)
            bigDeal
        end
        methods
            function self = BigProxy(bigDeal)
                self.bigDeal = bigDeal;
            end
            function value = get.hugeness(self)
                value = self.getHugeness;
            end
        end
        methods(Access = private)
            function value = getHugeness(self)
                if isa(self.bigDeal,'BigProxy')
                    value = self.bigDeal.getHugeness;
                else
                    value = self.bigDeal.hugeness;
                end
            end
        end
    end
    

    这将允许您执行以下操作

    >> b = BigDeal;
    >> pb = BigProxy(b);
    >> ppb = BigProxy(pb);
    

    每个 {b,pb,ppb} 都将具有相同的公共方法和属性。唯一的缺点是我不得不(不必要地恕我直言)用一个新的私有 getter 来混淆 BigProxy。

    【讨论】:

    • 其实getHugeness中的isa()测试是不需要的。它可以简单地是“function value = getHugeness(self); value = self.bigDeal.hugeness;”。一旦你在 get.hugeness Dependent 属性 getter 之外,似乎 .-reference 语法不再绕过 getter。我同意 - 这种额外的混乱是一个无赖。但是,Matlab 不这样做可能会很棘手,因为避免它需要在处理 .应用于输入参数与任何其他相同类型的变量时不同。
    • 不,等等 - 这应该很容易。 Matlab 可以像对待其他地方一样对待 .-reference 中的从属属性,而不是引发这个特殊错误。如果在 self 上调用,那么您将获得无限递归并破坏堆栈,并且 Matlab 可以在无限递归错误结束时发出“从其自己的 getter 调用的依赖属性”消息作为诊断帮助。如果在另一个相同类型的对象上调用,它的 getter 会被依次调用,在 BigProxy 这样的情况下,最终会得到一个真实的值。
    猜你喜欢
    • 1970-01-01
    • 2013-01-31
    • 2011-07-09
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    相关资源
    最近更新 更多