Matlab OOP - 重载大小()

Matlab OOP - Overloading size()

我想为我的 class 之一重载 size() 函数,这样它就不会 return 对象的大小,而是特定成员的大小。问题是 Matlab 在 class 构造函数中调用 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

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

的大小相同
a = dataClass(ones(100))

a = 

  100x100 dataClass array with properties:

  memberVar: [100x100 double]

解决方法是将重载实现为

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 

并调用 size(obj, 'mv') 但这违背了重载的全部目的,因为我想像调用任何其他对象一样调用 size()

有什么建议吗?

如果要为 class 重载 size,则需要格外小心 - 这既要小心实现事物的方式,也要小心设计你想要的 class 行为举止。

首先,请注意,您需要决定是否能够为 dataClass 对象制作数组,或者您是否愿意只制作标量 dataClass对象。如果您希望能够创建 dataClass 对象的数组,那么当给定这样一个数组时,您究竟希望 size 做什么?你想让它报告数组的大小,还是一个 dataClass 内的数据大小?哪个dataClass?您是否希望它在标量和数组上调用时切换行为?这很快就会让人感到困惑。

所以首先,我建议如果你想超载 size,你可能想要限制你的 class,这样就不可能使用标量以外的任何东西.您可以通过重载 cathorzcatvertcat 并让它们出错(小心,在完全正确的情况下)来做到这一点。

除此之外,您需要小心确保不仅 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

如果您还按照上面的建议重载了 cathorzcatvertcatnumel,我认为这可以满足您的要求。

不过,还有一点需要注意。您提到 MATLAB 在对象构造函数中调用 size 来确定其大小。实际情况并非如此 - 实际情况是,在您构造它之后,MATLAB 在命令行显示结果并调用 disp,然后调用 size 来确定大小。它将它报告为 dataClass 的 100x100 数组,但事实并非如此 - 它是具有 100x100 memberVar 的 1x1 数组。您可以通过尝试访问 a(2) 来测试它,这将出错。

所以你然后需要重载​​class的显示方法。您可以通过从 matlab.mixin.CustomDisplay 继承 class 或直接重载方法 disp and/or display 来做到这一点。让他们显示任何你想要的,比如 memberVar.

的内容

请注意最后一件事:在工作区浏览器中,a 被报告为 100x100 - 这又是 size 的输出。我希望您对此表示满意,因为据我所知,无法让大小向命令行报告一件事,而向工作区浏览器报告另一件事。

希望对您有所帮助 - 如您所见,重载 size 时需要考虑很多因素,这就是为什么通常不推荐这样做的原因。