MATLAB 在类调用类构造函数中创建的对象上用括号括起来


classdef Dog < handle
properties
data;
end
methods
function self = Dog(varargin)
disp("Dog()")
end
function out = new(~)
out = Dog();
out('bark') = 1;
end
end
end

d=Dog(); 为什么下面打印d.new()

Dog()
Dog()
Dog()

如果我超载,它也会绕过subsref。在控制台中输入d会给出

ans = 
1×114 Dog array with properties:
data

并且没有用d('bark') = 1复制.

如果我摆脱varargin,行为就会改变,而是出现错误。还有为什么1x114

以下是调用d.new()时(d = Dog()之后)发生的情况:

  1. out = Dog();被调用。此构造函数调用触发"Dog()"的第一个输出
  2. 调用
  3. out('bark') = 1;,这将触发以下内容:
    • 'bark'的字符被解释为值[98 97 114 107 ]。因此,Matlab 将out大小调整为 114。
    • 为了构造一个Dog对象来填充out[98 97 114 107 ]的位置,Matlab 再次调用构造函数,这次输入参数varargin等于{ 1 }。这将触发"Dog()"的第二个输出。
    • 为了构造一个Dog对象来填充out中的其他位置,Matlab 再次调用构造函数,这次没有输入参数。这将触发"Dog()"的第三个输出。

此外,subsref不会被绕过,而只是不被调用,因为您不会以读取方式引用对象。

当你删除varargin时,你会得到错误,因为不能再用一个输入参数调用构造函数,如上面 2. 下的第二个项目符号中所述。

据我了解,在类方法中,索引表达式始终使用内置的subsasgnsubsref,而不是您可能自己编写的重载(自定义)表达式。这样,重载这些函数不会删除类方法访问对象属性的能力。

因此,在您的类方法中,out(i)访问数组中的第i个对象out。这不是out.data(i)out实际上是类Dog的对象数组。Dog()创建一个 1x1 数组,您通常将其视为一个对象,但它实际上是一个数组。MATLAB 中的所有内容都是一个数组!

现在out('bark') = 1.'bark',正如 user16372530 的 anwser 所解释的那样,是一个 4 元素数组,数值[98 97 114 107]。因此,out从自定义类的 1x1 数组开始,大小调整为 114 个元素的数组,以及您1分配的 4 个元素。在这里,MATLAB 需要创建一个空元素来填充 113 个新元素,因此调用Dog()一次并将结果复制到每个元素中。然后它需要将1转换为您的类,因此调用Dog(1)执行此操作,并将结果复制到 4 个索引元素。实际上,如 user16372530 在下面的注释中,首先转换1,然后创建空对象。

如果你想让你的类方法使用重载的索引运算符,你需要显式调用subsasgnsubsref,这很丑陋且难以阅读。据我了解,确实没有办法在类方法中使用类对象,因为您实际上打算使用您的类。相同的代码在类方法内部和外部的行为不同。

MATLAB OOP有一些非常有趣的功能,但它也有很多奇怪和不方便的东西。我猜他们尽了最大的努力在以前存在的 MATLAB 数组语法中设计了一个自定义类系统。

相关内容

  • 没有找到相关文章