我如何创建一个属性在类,直接处理到另一个类对象

23日视图(30天)
目前我有两类,一个类包含一个结构化的定义,和另一个类,应该符合这个定义。myDefinition类加载数据文件的定义。
这是classdef和一些示例属性定义类:
classdefmyDefinition
属性(常量)
lengthMin = 8;
lenthMax = 64;
scaleDefault = [1];
结束
属性(GetAccess =公共SetAccess =不可变)
类型;
definitionFile;
地图;
元素= {};
结束
方法
函数obj = myDefinition (thistype filenameDefinition)
elementTable = readtable (filenameDefinition);
%遍历元素……
结束
结束
结束
函数是真的不重要,但是对于一个概述,myDefinition的构造函数中读取指定文件路径的字符串或字符数组filenameDefintion(这是一个csv文件),与readtable读取它,循环遍历行创建元素。
然后我有一个类必须遵循的一个定义myDefinition类。
classdefmyDefinedObject
属性(访问=私人)
mindatabits = 0;
maxdatabits = 64;
结束
属性(SetAccess =不可变,GetAccess =公共)
mydef;
类型;
名称;
一个;
x;
结束
方法
函数obj = myDefinedObject (num thisDefinition,数据)
如果isa (thisDefinition“myDefinition”)
obj。mydef = thisDefinition;
其他的
obj。mydef = [];
警告(“没有提供有效的定义文件”);
结束
%根据输入数量,名称和其他属性
%的定义,然后分析数据基于属性
%定义的查找
结束
结束
结束
我有其他方法在myDefinedObject以外的构造函数,关键是其中的一些方法需要存储在mydef的定义。确定需要做什么。这就是为什么我现在mydef myDefinedObject类的内部属性。
在一个典型的运行我的程序,我有一个或两个对象 myDefinition (可以是一个非常大的对象,内存明智)但可能有几十个的对象 myDefinedObject 。所以,理想情况下,mydef来说实际上是一种处理myDefinition对象,而不是对象本身的一个副本。
我知道我可以处理类
classdefmyDefinitionHandle <处理
属性(setAccess =不可变)
能延期的;
结束
函数obj = myDefinitionHandle (thisDefinition)
如果isa (thisDefinition“myDefinition”)
obj.def = thisDefinition;
其他的
obj.def = [];
警告(“没有提供有效的定义文件”);
结束
结束
结束
然后改变 myDefinedObject 检查一个 myDefinitionHandle 从而有效地定义一个句柄。
然而,现在处理一层当试图访问它在我的方法与我只是存储在每个定义本身 myDefinedObject 对象。例如,我有一个方法来检查obj。一个基于obj是正确的。类型值和定义是什么类型的定义:
函数obj =遵守(obj)
如果strlength (obj.a) > obj.mydef.def.elements {obj.type} .max
obj。一个= obj.a (1: obj.mydef.def.elements {obj.type} .max);
结束
结束
(注意:遵守从集被称为是一个方法,这是一个非常简化的例子)
我就会更喜欢打电话 obj.mydef.elements {obj.type} .max 而不是 obj.mydef.def.elements {obj.type} .max 班上的额外. def对象层真的无用武之地。
这些类结构有一个更好的方法我可以这样吗 mydef 直接点 thisDefinition 对象在构造函数中传递?
3评论
克里斯
克里斯 2023年1月17日
编辑:克里斯 2023年1月17日
这样的工作吗?这样我认为你必须设置在myDefinedObject和myDefinition对象必须存在(所以,将它传递给构造函数或setter)。手柄只设置一次,如果是myDefinition对象的变化,obj.mydef价值。元素指出仍然存在。
obj.mydef。= @ ()myDefinitionObj.elements元素
一些背景知识,以防你没有看到它:
https://undocumentedmatlab.com/articles/handle-object-as-default-class-property-value

登录置评。

接受的答案

队长Karnage
队长Karnage 2023年3月31日
这里是一个更轻的重量类,实现我最初的目标。类似于 HandleObject 内,它存储一个现有的对象作为“主人”属性。然后存储两种可能的版本的这个“主”属性:
  • 你可以让它只读(违约,或通过国旗的allowwrite参数的构造函数),构造函数将其存储在一个不变的主对象,immutableMaster,永远不会改变。
  • 你可以让它读写(通过真正的国旗的allowwrite参数的构造函数),构造函数使私人对象,privateMaster,通过内部变化的方法。注意,即使privateMasteristelf是私有财产,它本质上是一种公共财产像大多数RefObject对象上的操作会在私人的主人。你不能访问.privateMaster财产直接与dot-indexing它就像公共财产。
依赖房地产 myMaster 将返回 immutableMaster privateMaster 根据不变的 可写 属性,该属性设置= allowwrite 在构造函数中。生活的其他财产是后续未使用的对象。
我的 HandleObject 类重新创建原始对象使用 dynamicprops, RefObject 简单地使用重载函数 subsref subsasgn 分别指向所有下标引用和下标作业,回 myMaster 财产。这种方式, RefObject 类变量就像它是一个变量相同的类 myMaster 财产,
我知道的有两个例外(到目前为止):
  1. 类()函数将状态RefObject而不是主对象的类。然而,我添加了. class方法将报告的内部类的主人
  2. 元类()函数将同样给metaproperties RefObject类而不是主对象的类。然而,我添加了.Meta方法将报告的metaproperties硕士课程。
如果我找到其他的MATLAB函数不像,我也会把它们。
注意:这意味着名字 不会是可用的属性、方法或字段的主对象。RefObject类将覆盖任何访问,因此他们不会被从主,因此,可能会丢失在创建RefObject版本。然而,我怀疑任何这样的命名属性,方法或字段将被设计给在绝大多数情况下相同的输出。
有一件事我需要清理(对我的教诲,但在案例分享其他人也有同样的误解)——当你使用一个处理函数 HandleObject RefObject 并指定其他变量,对象。等内部的属性,它使一个初始的副本对象并将其存储在内存中。它不会创建一个处理/原始对象的指针。您可以删除原来的对象,它将不会影响到处理对象被分配它的价值。相反,一旦你创建一个处理对象,处理对象的任何副本/作业只会回到最初。虽然我有这样的误解,这仍然符合我的初衷不使用内存与同一对象的多个副本。
RefObject 也更多的真正的处理/指针-我发现 HandleObject 永远不会改变原来的主人。它只是复制它的属性和操作自己的属性的副本。它仍然具有有用性作为一个指针当你复印HandleObject本身,但使用更多的整体记忆。它也很棘手,因为试图指出主,没有任何方法为所有方法,因为工作 function_handle 有其局限性。 RefObject 到目前为止,我已经测试它,曾与每一个类中,属性,字段,和/或方法我试过所有类型和下标我能想到的,没有丑陋的变通,甚至本地MATLAB类型。
为什么我创建这些类?创建一个 处理 对象,可以指出,而不是创建新副本,但不添加一个额外的下标层访问所需的原始值。我变得非常长链的变量名对象嵌套对象嵌套对象通过使用一个主处理存储其他对象/类,简单的变量属性。这使我的变量名短,允许更灵活的使用的大型类与其他类的属性,没有使用了大量的内存。现在我免费大主类,得到重用,可以简单地创建一个RefObject版本的任何此类类复制里面的其他类供参考,没有复制整个原始对象每次。
其他差异/潜在问题:
  • MATLAB建议而不是使用subsrefsubsasgn每个人都应该使用matlab.mixin.indexing.RedefinesParen,matlab.mixin.indexing.RedefinesDot,matlab.mixin.indexing.RedefincesBrace相反,这表明MathWorks可能反对subsrefsubsasgn在未来。现在,对我来说这是更快,更容易实现,。
  • subsasgn逻辑可以使用改进,特别是在资源效率。它必须遍历所有通过下标两次——一次初始值,然后向后分配值。这就是我如何让它兼容几乎所有类型的类,它将潜到referece链,通过保持每个对象的一个副本,然后改变的元素需要改变在最后链中的对象,然后复制对象和随后的更高的对象。这样可以确保所有类型/类/结构maintainted。

更多的答案(2)

队长Karnage
队长Karnage 2023年1月23日
考虑了一会儿后,我提出了自己的解决方案。我尝试了一种“普世”的解决方案,将创建一个句柄几乎任何类的一个对象。
理论上,附加的类可以被用来克隆任何类,并创建一个句柄,它的所有属性,和一些相对较小的局限性。它使用的metaproperties类复制来确定它的所有属性和方法。如果他们是公开可读,然后创建自己的属性(使用 dynamicprops 这些公共属性 function_handle 这个公共方法。当然,它无法复制任何私人属性或方法,但因为它是一个处理,这些私有属性和方法将被调用时使用公共财产或方法依赖于他们,无论如何,所以我想不出任何问题,将创建的手。
在实践中,它曾与我所有的定制类到目前为止,但我没能做全面的测试来验证。如果别人遇到这个,希望反馈是否工作在其他各种类。
2的评论
队长Karnage
队长Karnage 2023年3月31日
这里有一个更多的文件,以防有人下载/使用我所版本。不过,我不推荐这门课。它仍然有一些问题,我认为这是过于复杂。我想出了一个更好的解决方案需要在另一个答案(称为“RefObject”),但这是我的这是最新版本的HandleObject以防RefObject不。
代码/评论并不完全清理干净,但我可能不会做任何更多的更新我不认为我将使用此了。

登录置评。


克里斯
克里斯 2023年1月18日
编辑:克里斯 2023年1月18日
@Captain Karnage 像这样吗?
mydef = myDefinition;
mydef, a = myDefinedObject ([] []);
mydef一
类属性名称大小字节1 x1 80 myDefinedObject mydef 1 x1 800 myDefinition
a.type
ans =function_handle与价值:
@ ()thisDefinition.type
a.type ()
ans = 10×10
92 99 8 67 74 51 58 40 98 80 7 73 55 57 64 16 41 4 81 88 70 22 54 56 63 47 60 62 69 71 85 87 19 21 28 86 93 25 2 9 61 68 24 76 83 90 75 52 34 17 42 49 26 33 65 23 48 32 39 66 79 82 89 91 6 13 95 97 29 31 38 45 72 10 12 94 96 78 35 37 44 46 53 11 18 100 77 84 36 43 50 27 59
1评论
队长Karnage
队长Karnage 2023年1月20日
有趣的方法。我没有considiered做一个函数句柄变量/对象将函数。我的第一想法是“另一个非法的特征吗?”I saw your answer before your additional comment... later I looked back and saw your comment and followed the link, which confirmed that thought.
发布你的回复之前,我做了一个“蛮力”解决方案的处理版本myDefinition了在“真正的”myDefinition对象和其属性复制到处理版本。做这份工作,但我希望我有看到这个解决方案。尽管经历让我想知道如果我能做一个通用的“处理”类型,可以复制任何其他类型的对象,但利用处理版本处理的子类 dynamicprops 作为超类。
起初,我想使用这个解决方案我还必须定义函数处理每一个属性我想访问(因为你有 obj。thisDefinition.type type = @ () ;在 myDefinedObject 这一个。类型也将从mydef返回类型。然而,我发现我可以引用子通过 .type a.mydef () 。奇怪,因为它真的是一个属性,它被称为一个函数……但作品。
我回顾我的问题,意识到我并不完全清楚一件事。如果我在一个 myDefinedObject 类变量,我很好有一层访问定义。所以, a.mydef.type 很好。当我在做一个单独的处理类包含myDefinition对象里面,我必须做点什么 a.mydefhandle.mydef.type ——这就是我想要避免的。我不希望 myDefinedObject 类本身处理。

登录置评。

类别

找到更多的在变量帮助中心文件交换

标签

s manbetx 845


释放

R2022b

社区寻宝

找到宝藏在MATLAB中央,发现社区如何帮助你!

开始狩猎!

翻译的