2012-01-13 93 views
3

我想通过(){}为我的一个MATLAB类重载索引。这可以通过为该类实现subsref来实现,并且工作正常。访问重载索引引用类的方法和属性

但是,我还希望通过.(即访问方法和属性)为此类保留索引的默认行为。我试着用下面的代码:

function x = subsref(this, S) 
    if strcmp(S(1).type, '{}') 
     % My own implementation here 
    elseif strcmp(S(1).type, '()') 
     % My own implementation here 
    elseif strcmp(S(1).type, '.') 
     x = builtin('subsref', this, S); 
    else 
     error('Unknown index variant.'); 
end 

然而,这并不工作,因为我不知道先验多少输出参数调用builtin('subsref', this, S)将返回。特别是,我的类的一个方法可能会返回可变数量的参数,输出参数的数量取决于其输入参数的数量和值。一个MATLAB example for subsref笔记:

When you implement a subsref method for a class, you must 
implement all subscripted reference explicitly [...] 

难道这真的是唯一可能的解决方案?对于复杂的方法,这基本上意味着复制了很多逻辑。这在我的情况下绝对是不可维护的(具有很多方法和属性的大类)。

注:我知道这是关于语法糖的,并且我总是可以使用标准方法调用而不是重载(){}

+1

重载subsref几乎不是一个好主意。那么你可以预见到更多的麻烦。如果你可以描述为什么你试图重载subsref和你试图解决的问题,有人可能会建议比这种方法更好的解决方案。 – Kavka 2012-01-14 15:01:38

+1

@Kavka:操作符重载一般是一个困难的话题,关于它的优点和缺点一直存在很长的争论。就我而言,我正在编写一个类似列表的对象,通过'()'和'{}'进行索引是自然的扩展。正如我在我原来的文章中所说的那样,重载操作符通常是关于语法糖的,通过普通的方法/属性也可以实现。尽管如此,重载操作符__可以使代码更简洁明了,如果它们实现的很好。 – 2012-01-16 07:08:16

+0

我的两分钱:特别是对于Matlab,subsasgn和subsref很繁琐(即使对于运算符重载机制),但在某些情况下它们是值得的,因为在Matlab中索引是如此惯用。特别是如果你正在做嵌套索引。对于使用索引的多态代码来说,这是非常必要的。我只为少数课程(可能是其中的1%)做过这些,但我在所有时间都使用这些覆盖的操作符。 – 2012-01-17 17:15:01

回答

3

对于部分修复,我认为你可以使用nargout来服从调用者,而调用者通常会处于知道的位置。捕获多个输出的任何功能必须在通话时知道它捕获了多少个。

这不会让你在命令行显示多个argout,但应该像捕获返回值一样工作,就像在大多数代码中一样。

function varargout = subsref(this, S) 
    switch S(1).type 
     ... 
     case '.' 
     varargout = cell(1, nargout); 
     if nargout == 0 
      builtin('subsref', this, S); 
     else 
      [varargout{:}] = builtin('subsref', this, S); 
     end 
    end 
end 

买者自负:这个代码不进行测试,并有一帮的subsref/subsasgn里面的东西挑剔的边缘情况。

+0

一个好主意。如果调用者提供的参数数量错误(因为他们会在'subsref'中得到一个错误,而不是他们认为他们正在调用的方法),但是我想你必须忍受如果你重载运营商。 – 2012-01-16 07:02:41

相关问题