如何在使用 MATLAB Class 文件夹创建的 class 对象中创建成员 public?

How to make a member public in an class object created using MATLAB Class folder?

我正在尝试重用一个包,其中所有 classes 都是使用 Class 文件夹编写的,即所有方法都是文件夹 @myclassname 中的文件。我想读取 class 对象的成员。在正常的 classdef classes 中,声明一个 属性 public 可以解决问题。就我而言,我没有找到任何解决方案,我不想重写整个包。

解释我的问题的最小示例: 简单 class: \MatlabPath\@mytestclass\mytestclass.m

%myconstructor
function res =mytestclass()
st.a=1;
res=class(st,mfilename);
end

当前行为:

>> obj=mytestclass();
>> obj.a
Access to an object's fields is only permitted within its methods.

期望:

>> obj=mytestclass();
>> obj.a
ans =
1

谢谢

我知道您不想重写整个包,但如果 属性 访问很重要,您可能更喜欢它而不是实际的解决方案。

在第一个 MATLAB OOP classes 中,按照您的指示进行组织(所有方法都在一个文件夹中),程序员必须编写自己的 subsref and subsasgn 方法,如果他们想要自定义访问他们的 class属性。

我必须说我确实玩过它,但很快就放弃了,因为构建简单的 classes 非常乏味。 MATLAB 可能注意到了这一点,并在后来的版本中引入了新的 Classdef 模型。尽管仍然有一些快速(由于 MATLAB 按值传递几乎所有内容),这个 Classdef 模型比旧公式更方便。

如果你想坚持使用旧模型,我可以给你一个极简主义的例子,它会给你想要的行为。如果您只对公开一些属性感兴趣,您可以复制几次。如果您打算公开包的所有属性,那么我向您保证,重写包比将我的解决方案应用于广泛的现有代码库更省力。

因此在您的文件夹中:\MatlabPath\@mytestclass\,您现在需要两个文件:

mytestclass.m(例如,我添加了几个不同的属性)

function res =mytestclass()
    st.scalar = 1 ;
    st.array  = [1 2 3] ;
    st.cellarray = {'1' '2' '3'} ;
    res=class(st,mfilename);
end

和你自己的 subsref.m:

function out = subsref(obj,S)

thisS = S(1) ;

if strcmp(thisS.type , '.')
    out = obj.(thisS.subs) ;
    
elseif strcmp(thisS.type , '{}')
    % You might have to code this case too
    
elseif strcmp(thisS.type , '{}')
    % You might have to code this case too
end

% recursive call if the struct S has more than one element
if numel(S) > 1
    S(1) = [] ;
    out = subsref(out,S) ;
end

end

有了它,您现在可以访问您的属性:

>> obj.scalar
ans =
     1
>> obj.array
ans =
     1     2     3
>> obj.cellarray
ans = 
    '1'    '2'    '3'

这个最小的 subsref 也适用于对数组进行索引:

>> obj.array(2:end)
ans =
     2     3
>> obj.cellarray(2)
ans = 
    '2'

它也适用于赋值:

>> obj.scalar = 125 ;
>> obj.scalar
ans =
   125
>> obj.array(2:end) = [8 9] ;
>> obj.array
ans =
     1     8     9

请记住,这是一个最小的示例,某些 属性 类型可能无法很好地响应这些简单的情况,在这种情况下,您将必须添加特定的代码来处理每个特定的情况。

给出了正确的解决方案,并允许自定义可以访问的成员。您甚至可以设计 class,这样您就可以 'index' 使用不匹配任何成员的名称。

但是如果你只想公开所有 class 成员,你可以将 subsref 函数简化为:

function out = subsref(obj,S)
out = builtin('subsref',obj,S);