Products & Services Solutions Academia Support User Community Company

Learn more about MATLAB   

Creating Object Arrays

Building Arrays in the Constructor

A constructor function can return an object array by making the necessary assignments when initializing the output argument. For example, the following DocArrayExample class creates an m-by-n object array and initializes the Value property of each object to the corresponding element in the input argument F:

classdef DocArrayExample
   properties
      Value
   end
   methods
      function obj = DocArrayExample(F)
         if nargin ~= 0 % Allow nargin == 0 syntax
            m = size(F,1);
            n = size(F,2);
            obj(m,n) = DocArrayExample; % Preallocate object array
            for i = 1:m
               for j = 1:n
                  obj(i,j).Value = F(i,j);
               end
            end
         end
      end
   end
end

Initializing Arrays of Value Objects

To initialize the object array, the class constructor calls itself recursively with no arguments. MATLAB might need to call the constructor with no arguments even if the constructor does not itself build an object array. For example, suppose you have a class defined as follows:

classdef SimpleClass
   properties
      Value
   end
   methods
      function obj = SimpleClass(v)
         obj.Value = v;
      end
   end
end

Now suppose you execute the following statement (which is valid MATLAB code):

a(1,7) = SimpleClass(7)
??? Input argument "v" is undefined.

Error in ==> SimpleClass>SimpleClass.SimpleClass at 7
         obj.Value = v;

This error occurs because MATLAB is attempting to call the constructor with no arguments to initialize elements in the array a(1,1:6).

Therefore, you must ensure the constructor function supports the no input argument syntax. The simplest solution is to test nargin and let the case when nargin == 0 execute no code, but not error:

classdef SimpleClass
   properties
      Value
   end
   methods
      function obj = SimpleClass(v)
         if nargin > 0
            obj.Value = v;
         end
      end
   end
end

You might also want to provide a default for the property in the properties definition block or assign a value to the input argument in the constructor, if there are no arguments specified.

Using the revised class definition, the previous array assignment statement executes properly:

a(1,7)=SimpleClass(7)
a = 
  1x7 SimpleClass
  Properties:
    Value

The object assigned to a(1,7) used the input argument when MATLAB created it:

a(1,7)
ans = 
  SimpleClass
  Properties:
    Value: 7

However, MATLAB created the objects contained in a(1,1) through a(1,6) with no input argument and initialized the value of the Value property to empty []. For example:

a(1,1)
ans = 
  SimpleClass
  Properties:
    Value: []

Initial Values of Object Array Properties

When MATLAB calls a constructor with no arguments to initialize an object array, all property values are assigned whatever values are specified in the property definition block, assigned in the constructor in an if nargin == 0 block, or default to the value of empty double (i.e., []).

Creating Empty Arrays

All classes have a static method named empty that creates an empty array belonging to the class. Empty arrays have no instance data. This method enables you to specify the dimensions of the output array, but at least one of the dimensions must be 0. For example:

emptyArray = myClass.empty(5,0);

creates a 5–by–0 empty array of myClass objects. Calling empty with no arguments returns a 0–by–0 empty array.

Arrays of Handle Objects

Whenever MATLAB software creates a unique instance of a handle class, it calls the class's constructor. Recall that copies of handle objects reference the same data as the original and, therefore, are not unique. This behavior enables you to keep track of the number of instances that have been created for any given handle class in a MATLAB session.

You can use a persistent variable to record the number of times MATLAB calls the constructor. For example, the following class increments the persistent variable objCount each time the constructor is called:

classdef CountObjs < handle
   properties
      ThisCount
   end
   methods
      function obj = CountObjs
         persistent objCount
         if isempty(objCount)
            objCount = 1;
         else
            objCount = objCount + 1;
         end
         obj.ThisCount = objCount;
      end
   end
end

The property objCount contains the number of instances of the CountObjs class that have been created.

Initializing a Handle Object Array

It is sometimes useful to initialize an array by assigning to the last element (the element with the highest index values) in the array first. For example:

A(4,5) = CountObjs;
A(4,5).ThisCount

ans =

     1

As expected, the element in the index location 4,5 is the first instance of the CountObjs class. And element 1,1 is the second instance:

A(1,1).ThisCount

ans =

     2

However, this second instance is assigned for all remaining array elements:

A(2,2).ThisCount

ans =

     2

When initializing an object array, MATLAB assigns a single default object to the empty elements in the array. This approach reduces the number of calls to the class constructor. which otherwise would result from a single assignment statement when there are empty array elements. MATLAB gives each object a unique handle so that you can later assign unique property values to each object. This means that:

A(1,1) == A(2,2)
ans =

     0

Calling Constructor During Assignment from subsasgn

You can control what happens when you use an object in an assignment statement by implementing a class method called subsasgn for the object's class. The example above uses the CountObjs class to keep track of the number of instances created to illustrate how MATLAB initializes an object array. Suppose you want to change the default behavior so that MATLAB creates a new instance for each empty element of an array created with an initialization statement of the form:

A(r,c,p,...) = ClassConstructor;

where r, c, p are the maximum index values for the respective dimensions.

function a = subsasgn(a,s,obj)
   indices = [s.subs{:}];
   if ischar(indices) || ~isequal(length(s.subs),length(indices))
      error('CountObjs:subsasgn:nonscalar_index',...
         'Array indices must be scalar')
   end
   lastindex = prod(indices);
   switch s.type
      case '()'
         if any(indices > 1)
            % Convert LHS to CountObjs class from double
            % which is the result of empty array elements
            a = CountObjs;
            % Use linear array indexing
            for k=1:lastindex - 1
               a(k) = CountObjs;
               % Adjust Count due to class conversion
               a(k).ThisCount = a(k).ThisCount - 1;
            end
               % Put the first instance in the last element
            a(lastindex) = obj;
            if length(indices) > 1
               a = reshape(a,indices);
            end
         else
            a = obj;
         end 
   end
end

Adding this subsasgn method to the CountObjs class provides control over how MATLAB initializes arrays of CountObjs objects that have empty elements.

A(4,5) = CountObjs;
A(4,5).ThisCount

ans =

     1
A(1,1).ThisCount

ans =

     2
A(2,1).ThisCount

ans =

     3

See Indexing Multidimensional Arrays and Reshaping Multidimensional Arrays for information on array manipulation. See Specializing Object Behavior fro information on implementing subsasgn methods for your class.

  


Recommended Products

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.

 © 1984-2009- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS