函数句柄作为类的属性-Matlab

函数句柄作为类的属性-Matlab,matlab,class,function-handle,Matlab,Class,Function Handle,我定义了一个类,其唯一属性是函数句柄的单元格数组: classdef CellArrayHandle < handle properties cel % cell array of function handles end end Matlab说“达到了500的最大递归限制”,所以它似乎被理解为无限递归。然而,鸟鸣起作用的是: f = @(x) f(x) + 0.5; 对于函数句柄f 似乎当我将函数句柄作为属性封装到类中时,上面的

我定义了一个类,其唯一属性是函数句柄的单元格数组:

classdef CellArrayHandle < handle    
    properties
        cel  % cell array of function handles    
    end 
end
Matlab说“达到了500的最大递归限制”,所以它似乎被理解为无限递归。然而,鸟鸣起作用的是:

  f = @(x) f(x) + 0.5;
对于函数句柄f

似乎当我将函数句柄作为属性封装到类中时,上面的更新方法将不起作用

我不明白前者和后者的区别。在这一点上有人能帮我吗?多谢各位

致以最良好的祝愿


弗兰克

这种差异源于:

您可以将句柄对象指定给多个变量或将其传递给函数,而无需使MATLAB复制原始对象

或者,借用Highlander的原始思想,当您实例化一个句柄类时,“只能有一个”(内存中实例的glob,其中所有变量只分配给创建引用,而不是新副本)

考虑示例脚本:

f = @(x) x;
f = @(x) f(x) + 0.25;
f = @(x) f(x) + 0.50;

b = CellArrayHandle();
b.cel{1} = @(x) x;
b.cel{1} = @(x) b.cel{1}(x) + 0.25;
b.cel{1} = @(x) b.cel{1}(x) + 0.5;

fval = f(1);
bval = b.cel{1}(1);
如果我调试此脚本并在
fval
求值之前查看堆栈,我会看到:

K>> dbstack
> In @(x)x
  In @(x)f(x)+0.25
  In @(x)f(x)+0.5
因此,在创建后续
f
句柄的过程中,Matlab能够创建当前
f
函数句柄的副本,并可以形成一个堆栈

当我对
b
执行相同的操作时,我得到以下结果:

K>> dbstack
> In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  ...
这是因为对
b
的属性的每次赋值都会使
b
的属性值,而不会创建类的新实例。因此赋值本质上是无限递归的

您可以通过不让类从
句柄继承,而是从
值继承(默认值)来修复此问题。通过从
classdef
中删除
,并重复handle调用的
dbstack
,我们可以

K>> dbstack
> In @(x)x
  In @(x)b.cel{1}(x)+0.25
  In @(x)b.cel{1}(x)+0.5
这是因为对
b
属性的每个赋值现在都会复制当前的
b
,实例化一个新的
b
,并将
b
的旧定义存储在函数句柄中以形成适当的堆栈

K>> dbstack
> In @(x)x
  In @(x)b.cel{1}(x)+0.25
  In @(x)b.cel{1}(x)+0.5