Matlab OOP - 重载大小()

pha*_*ann 3 oop matlab overloading

我想重载size()我的一个类的函数,以便它不返回对象的大小,而是返回特定成员的大小.问题是Matlab在类构造函数中调用obj.size以确定对象数组的大小.

例如:

classdef dataClass < handle

properties
    memberVar
end

methods 
    function obj = dataClass(mvIn)
        if nargin ~= 0
            if ~ismatrix(mvIn)
                error('Input must be a matrix');
            end

            obj.memberVar = mvIn;
        end
    end

    function sz = size(obj, varargin)
        h = @(x)builtin('size', x, varargin{:});
        sz = cell2mat(cellfun(h, {obj.memberVar}', 'uni', 0));
    end       
end

end
Run Code Online (Sandbox Code Playgroud)

不起作用,因为对象数组的大小与memberVar的大小相同

a = dataClass(ones(100))

a = 

  100x100 dataClass array with properties:

  memberVar: [100x100 double]
Run Code Online (Sandbox Code Playgroud)

解决方法是将重载实现为

function sz = size(obj, varargin)
    idx = strcmpi(varargin, 'mv');
    if any(idx)
        varargin = varargin(~idx);
        h = @(x)builtin('size', x, varargin{:});
        sz = cell2mat(cellfun(h, {obj.memberVar}', 'uni', 0));
    else
        sz = builtin('size', obj, varargin{:});
    end
end 
Run Code Online (Sandbox Code Playgroud)

并且调用size(obj, 'mv')但是这会破坏重载的整个目的,因为我想像size()任何其他对象一样调用.

有什么建议?

Sam*_*rts 5

如果你想size为一个类重载,你需要非常小心- 在你如何实现的过程中要小心,并在设计中仔细考虑你希望类的行为方式.

首先,请注意,您是否希望能够创建dataClass对象的数组,或者您是否只使用标量dataClass对象.如果您希望能够创建dataClass对象数组,那么size在给定这样的数组时您想要做什么?您是否希望它报告数组的大小或数据的大小dataClass?哪个dataClass?您是否希望它在标量和数组上调用时切换行为?那会很快混乱.

首先,我建议如果你想重载size,你可能想要限制你的类,这样就不可能使用除标量之外的任何东西.你可以通过重载cat,horzcat并且vertcat让它们出错(仔细地,在恰当的情况下)来做到这一点.

除此之外,您还需要小心确保不仅会过载size,而且还要过载numel.sizenumel以一些非显而易见的方式进行交互.

所以说,你应该能够实现这样的事情:

classdef dataClass < handle

properties
    memberVar
end

methods 
    function obj = dataClass(mvIn)
        if nargin ~= 0
            if ~ismatrix(mvIn)
                error('Input must be a matrix');
            end

            obj.memberVar = mvIn;
        end
    end

    function sz = size(obj, varargin)
        sz = builtin('size', obj.memberVar, varargin{:});
    end       
end

end
Run Code Online (Sandbox Code Playgroud)

如果你还超载cat,horzcat,vertcatnumel上面建议,我认为这确实你问什么.

但是,还有一件事需要注意.您提到MATLAB size在对象构造函数中调用以确定其大小.事实并非如此 - 正在发生的事情是,在构建它之后,MATLAB在命令行显示结果并执行调用disp,然后调用size以确定大小.它报告它是一个100x100阵列dataClass,但事实并非如此 - 它是1x1阵列,100x100 memberVar.您可以通过尝试访问来测试这个a(2),这将是错误的.

因此,您需要重载该类的显示方法.您可以通过从中继承您的类matlab.mixin.CustomDisplay,或直接重载方法disp和/或来完成此操作display.让它们显示您想要的任何内容,例如memberVar.

最后要注意的一点是:在工作区浏览器中,a报告为100x100 - 这又是输出size.我希望你对此感到满意,因为我不知道如何向命令行报告一个大小,向工作区浏览器报告另一个大小.

我希望这有帮助 - 正如你所看到的,在重载时需要考虑很多size,这就是为什么它通常不推荐.