6

Given a structure, is there a way to create a class in MATLAB? Take for instance

>> p = struct(); p.x = 0; p.y = 0;
>> p

p = 

    x: 0
    y: 0

>> name = 'Point'

name =

Point

What I would like to do, is given a string containing the name of the class and a struct with containing the fields I would like to create a class without having to write a file explicitly writing the definition.

Right now if we use class(p) we will obtain struct. What I want to do is create an object of the type Point so that when I do class(obj) then I get Point.

Any ideas how to accomplish this besides writing a file in MATLAB with the class definition and then executing it?

Amro
  • 123,847
  • 25
  • 243
  • 454
jmlopez
  • 4,853
  • 4
  • 40
  • 74
  • What do you need dynamically created classes for? – Jonas Sep 11 '11 at 12:05
  • @Jonas, I have a binary file with information about structures and its information. The information includes the name of the class, the fields it contains and the datatype of the fields. I can read this information and store it in a simple struct in MATLAB, but I won't know the type of object that the struct is. I want to be able to construct this objects on the fly with the instructions of the binary file. – jmlopez Sep 11 '11 at 16:12
  • What about storing data in a struct-array with fields `Name` and `Data` where data is a struct with, like the name says, data. – Mikhail Poda Sep 11 '11 at 18:22
  • @Mikhail, I thought about that but that would require the user to access an extra field: `p.Data.field1`. I think I'll just make MATLAB write a file with the class definition and then create an object of that type using `str2func` to get the handle of the newly created class constructor. – jmlopez Sep 11 '11 at 18:47

3 Answers3

4

Either you have specific functionality (methods) associated with the Point class as opposed to e.g. the Line class, in which case you should write out the classes by hand, anyway, or you can make a single dynamicprops class that can have dynamically created properties, and unless you really need to call a method named class, you much simplify your life by calling classname instead.

classdef myDynamicClass < dynamicprops
properties (Hidden)
myClass %# this stores the class name
end
methods
function obj = myDynamicClass(myClassName,varargin)
%# synopsis: obj = myDynamicClass(myClassName,propertyName,propertyValue,...)
%# myClassName is the name of the class that is returned by 'classname(obj)'
%# propertyName/propertyValue define the dynamic properties

obj.myClass = myClassName;

for i=1:2:length(varargin)
addprop(obj,varargin{i})
obj.(varargin{i}) = varargin{i+1};
end
end

function out = classname(obj)
out = obj.myClass;
end

end 
end
Jonas
  • 74,690
  • 10
  • 137
  • 177
  • I sort of like this. If I call `class` an a `myDynamicClass` object I will obtain `myDynamicClass`. I can use this to then check for the real classname by using the function defined there. This will behave better than just a struct because it will check to see if it has the right fields. Thanks Jonas, now I won't have to write a different file for every class specified in the binary file. – jmlopez Sep 12 '11 at 13:34
  • @jmlopez: You're welcome. Note that you can also create set and get methods for the dynamic properties, so that you can add additional functionality for e.g. error checking. – Jonas Sep 12 '11 at 13:39
  • back in '11 I should have said, "Oh really? How can I create the set and get methods for my dynamic properties?", After having a struggle thinking about how to do this I came up with [this](http://stackoverflow.com/a/20810965/788553). Is that the proper way to create the set methods? – jmlopez Dec 28 '13 at 04:30
1

I don't know of any way of creating objects dynamically, so I'd say the answer to your question is no. However, to solve your problem, I would propose something very similar to what Mikhail said:

Work with a struct with fields x, y and classname:

p.x=0;
p.y=0;
p.classname='Point';

and then write a function myclass(x) which returns x.classname. If for some reason you need to use class() you could even overload it with your own function which checks if x is one of your special structs and calls builtin('class', x) otherwise:

function out=class(varargin)
if nargin==1 && isstruct(varargin{1}) ... #check if we were given a struct
   && isfield(varargin{1}, 'classname') ... #...which contains a field classname
   && ischar(varargin{1}.classname) %# ... which is a string
    out=varargin{1}.classname; %# ok, our special case :-)
else
    out=builtin('class',varargin{:}); %# normal case - call builtin class()
end
Jonas Heidelberg
  • 4,984
  • 1
  • 27
  • 41
1

One solution that I've used in the past is to write a MATLAB function that takes this information (i.e. the class name and fields) and writes an M-file containing the required classdef construct.

This works well if you're using this information to describe a prototype that you want to expand later.

Nzbuu
  • 5,241
  • 1
  • 29
  • 51