How do I create a property in a class that is a direct handle to another class object
6 views (last 30 days)
Show older comments
Currently I have two classes, a class that contains a structured definition, and another class that is supposed to fit that definition. The myDefinition class loads the definition from a data file.
Here is the classdef and are some example properties from the definition class:
classdef myDefinition
properties(constant)
lengthMin = 8;
lenthMax = 64;
scaleDefault = [1 1];
end
properties( GetAccess = public, SetAccess = immutable )
type;
definitionFile;
map;
elements = {};
end
methods
function obj = myDefinition (thistype, filenameDefinition)
elementTable = readtable(filenameDefinition);
%Loops through elements here...
end
end
end
The function is really not important, but for an overview, the constructor for myDefinition reads the file in the path specified by the string or char array in filenameDefintion (which is a csv file), reads it in with readtable, and loops through the rows to create the elements.
I then have a class which has to follow one of the definitions in a myDefinition class.
classdef myDefinedObject
properties ( Access = private )
mindatabits = 0;
maxdatabits = 64;
end
properties ( SetAccess = immutable, GetAccess = public )
mydef;
type;
name;
a;
x;
end
methods
function obj = myDefinedObject( num, thisDefinition, data )
if isa(thisDefinition, 'myDefinition')
obj.mydef = thisDefinition;
else
obj.mydef = [];
warning('No valid definition file provided');
end
%Based on the number input, gets name and other properties from
%the definition, then parses the data based on the properties
%from the lookup in the definition
end
end
end
I have other methods in myDefinedObject other than the constructor, and the key point is that some of those methods need the definition that's stored in mydef. To determine what needs to be done. That is why I currently have mydef as an internal property of the myDefinedObject class.
In a typical run of my program, I have one or two objects of myDefinition (which can each be a very large object, memory wise) but could have dozens of objects of myDefinedObject. So, ideally, mydef would actually be a handle to a myDefinition object, rather than a copy of the object itself.
I know I can make a handle class
classdef myDefinitionHandle < handle
properties(setAccess = immutable)
def;
end
function obj = myDefinitionHandle(thisDefinition)
if isa(thisDefinition, 'myDefinition')
obj.def = thisDefinition;
else
obj.def = [];
warning('No valid definition file provided');
end
end
end
And then change myDefinedObject to check for a myDefinitionHandle and thus effectively have a handle to the definition.
However, the handle is now another layer away when trying to access it in my methods versus when I just stored the definition itself in every myDefinedObject object. For example, I have a method to check that a obj.a is correct based on the obj.type value and what is defined for that type in the definition:
function obj = comply(obj)
if strlength(obj.a) > obj.mydef.def.elements{obj.type}.max
obj.a = obj.a(1:obj.mydef.def.elements{obj.type}.max);
end
end
(Note: comply is a method that is called from set.a, and this is a very simplified example)
I would much prefer just to call obj.mydef.elements{obj.type}.max instead of obj.mydef.def.elements{obj.type}.max as the additional .def object layer in the class really serves no purpose.
Is there a better way I can structure these classes to make it so that mydef directly points to the thisDefinition object passed in the constructor?
3 Comments
Chris
on 17 Jan 2023
Edited: Chris
on 17 Jan 2023
Does something like this work? I think you would have to set it like this in myDefinedObject, and the myDefinition object would have to exist (so, pass it to the constructor or setter). The handle is only set once--if something changes in the myDefinition object, the value obj.mydef.elements points to remains.
obj.mydef.elements = @() myDefinitionObj.elements
some background, in case you haven't seen it:
https://undocumentedmatlab.com/articles/handle-object-as-default-class-property-value
Answers (2)
Chris
on 18 Jan 2023
Edited: Chris
on 18 Jan 2023
@Captain Karnage like so?
mydef = myDefinition;
a = myDefinedObject([],mydef,[]);
whos mydef a
a.type
a.type()
See Also
Categories
Find more on Data Type Identification in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!