1

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

解释我的问题的最小示例:简单类:\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

谢谢

4

2 回答 2

3

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

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

我必须说我确实玩过它,但很快就放弃了,因为构建简单的类非常乏味。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

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

于 2020-11-06T17:12:05.853 回答
3

Hoki 的回答给出了正确的解决方案,并允许自定义可以访问哪些成员。您甚至可以设计该类,以便您可以使用与任何成员不匹配的名称“索引”。

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

function out = subsref(obj,S)
out = builtin('subsref',obj,S);
于 2020-11-06T17:40:51.220 回答