gpt4 book ai didi

Matlab OOP - 重载大小()

转载 作者:太空宇宙 更新时间:2023-11-03 20:21:01 29 4
gpt4 key购买 nike

我想为我的一个类重载 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

不起作用,因为对象数组的大小与 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() 就像我对任何其他对象。

有什么建议吗?

最佳答案

如果您想为一个类重载size,您需要格外小心——在实现事物的方式上要小心,在设计您希望类的行为方式时也要小心。

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

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

除此之外,您需要小心确保不仅重载了size,还重载了numelsizenumel 以一些不明显的方式交互。

话虽如此,你应该能够实现这样的东西:

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) 来测试它,这会出错。

因此您然后需要重载​​该类的显示方法。您可以通过从 matlab.mixin.CustomDisplay 继承您的类,或通过直接重载方法 disp 和/或 display 来做到这一点。让它们显示任何你想要的,比如 memberVar 的内容。

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

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

关于Matlab OOP - 重载大小(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28343844/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com