You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab 2020a中如何在自定义类中重载A{n}?

Matlab中subsref重载的疑问与解决方案

背景知识

Matlab重载subsref方法时,通常用switch语句区分索引类型并获取索引值,常见三种索引处理逻辑:

  1. 圆括号索引(A(n))
switch S.type
case '()'
    B = A(S.subs{:});
end
  1. 大括号索引(A{n})
    某2014年书籍中的示例代码如下,但其中的.CellProperty让人困惑:
%大括号索引操作:A{n}
switch S.type
    case '{}'
       B = A.CellProperty{S.subs{:}};    %CellProperty是什么?
end
  1. 成员索引(A.name1)
%成员索引操作:A.name1
switch S.type
case '.'
   switch S.subs
   case 'name1'
      B = A.name1;
   case 'name2'
      B = A.name2;
   end
end

核心疑问:圆括号和成员索引的代码逻辑清晰,但大括号索引里的.CellProperty是什么?为什么不能直接写B = A{S.subs{:}}?

为验证问题,我基于多项式类MPolynom做实验,目标是实现p{2}的重载,期望返回多项式在x=2处的值(与p(2)结果一致,为29)。


基础可运行示例代码

以下代码已实现p(2)的功能,运行后能得到正确结果:

classdef  MPolynom
    properties
        coef;    %多项式系数
    end
    methods
        function obj = MPolynom(c)   %构造函数
            if isa(c,'MPolynom')
                obj.coef = c.coef;
            else
                obj.coef = c(:)';
            end
        end
        function plot(obj)    %重载plot函数
            r = max(abs(roots(obj.coef)));
            x = (-1.1:0.01:1.1)*r;
            y = polyval(obj.coef,x);
            plot(x,y);
            xlabel('X')
            ylabel('Y','Rotation',0)
            grid on
        end
        function r = plus(obj1,obj2)
            if ~isa(obj1,'MPolynom')       %如果第一个参数不是类MPolynom对象
                obj1 = MPolynom(obj1);    %创建一个类MPolynom对象obj1
            end
            if ~isa(obj2,'MPolynom')       %如果第二个参数不是类MPolynom对象
                obj2 = MPolynom(obj2);    %创建一个类MPolynom对象obj2
            end
            k = length(obj2.coef) - length(obj1.coef);   %计算两个阵列的长度差
            %创建一个类MPolynom对象作为返回值
            r = MPolynom([zeros(1,k) obj1.coef]+[zeros(1,-k) obj2.coef]);
        end
        function b = subsref(a,s)     %下标索引引用的实现
            switch s(1).type
               case '()'          %圆括号类型的引用 此处可设置断点
                    ind = s.subs{:};
                    b = polyval(a.coef,ind);  %返回多项式的值
                case '.'         %“.”类型的引用
                    switch s(1).subs
                        case 'coef'
                            b = a.coef;
                        case 'plot'     %由于方法plot没有返回值,这里单独列出访问过程
                            a.plot;
                        otherwise        %其他带返回值方法的引用
                            if length(s)>1
                                b = a.(s(1).subs)(s(2).subs{:});  %带输入参数的方法引用
                            else
                                b = a.(s.subs);  %不带输入参数的方法引用
                            end
                    end
                otherwise
                    error('Specify value for x as obj(x)')
            end
        end
        function y = polyval(obj,x)   %计算多项式对象obj在x处的值
            y = polyval(obj.coef,x);
        end
    end
end

运行测试代码:

p=MPolynom([1,3,2,5]);
p(2)
% 输出结果:
% ans =
%     29

错误尝试说明

尝试1:直接使用a.{s.subs{:}}

修改subsref中的大括号索引处理逻辑后,无法创建对象p=MPolynom([1,3,2,5]),也无法添加断点:

function b = subsref(a,s)     %下标索引引用的实现
    switch s(1).type
       case '{}'          %大括号类型的引用
            ind = a.{s.subs{:}};  % 语法错误,Matlab不支持这种写法
            b = polyval(a.coef,ind);  %返回多项式的值
        % 其他代码不变
    end
end

尝试2:照搬书籍中的.CellProperty

这种方式能正常创建对象,但执行p{2}时会报错:Unrecognized method, property, or field 'CellProperty' of class 'MPolynom'

function b = subsref(a,s)     %下标索引引用的实现
    switch s(1).type
       case '{}'          %大括号类型的引用
            ind = a.CellProperty{s.subs{:}};  % 错误:MPolynom类未定义CellProperty属性
            b = polyval(a.coef,ind);  %返回多项式的值
        % 其他代码不变
    end
end

正确实现p{2}重载的方法

书籍中的.CellProperty只是示例占位符,代表类中实际存在的单元格类型属性。对于MPolynom类,我们的目标是让p{2}返回多项式在x=2处的值,因此直接从s.subs中提取索引值即可,无需访问额外属性。

修改后的subsref方法如下:

function b = subsref(a,s)     %下标索引引用的实现
    switch s(1).type
       case '()'          %圆括号类型的引用
            ind = s.subs{:};
            b = polyval(a.coef,ind);  %返回多项式的值
       case '{}'          %大括号类型的引用
            ind = s.subs{:};  % 直接获取大括号中的索引值
            b = polyval(a.coef,ind);  % 复用圆括号索引的计算逻辑
        case '.'         %“.”类型的引用
            switch s(1).subs
                case 'coef'
                    b = a.coef;
                case 'plot'     %由于方法plot没有返回值,这里单独列出访问过程
                    a.plot;
                otherwise        %其他带返回值方法的引用
                    if length(s)>1
                        b = a.(s(1).subs)(s(2).subs{:});  %带输入参数的方法引用
                    else
                        b = a.(s.subs);  %不带输入参数的方法引用
                    end
            end
        otherwise
            error('Specify value for x as obj(x) or obj{x}')
    end
end

测试修改后的代码:

p=MPolynom([1,3,2,5]);
p{2}
% 输出结果:
% ans =
%     29

内容的提问来源于stack exchange,提问作者bokabokaboka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 19:45:55