Reputation: 142
That's a terrible title, but let me try to explain. I have a class test_class
that may be constructed one of two ways. I can create a single object with default properties by calling test_obj = test_class
, or I can create an array of objects with default properties by calling test_obj_array = test_class([x,y])
. Here's the full code:
classdef test_class
properties
A;
end
properties (Dependent = true)
B;
end
methods
function obj = test_class(S)
if nargin == 0
obj.A = 1;
else
x = size(S,1);
y = size(S,2);
obj(x,y) = test_class;
end
function B_value = get.B(obj)
B_value = obj.A * 2;
end
end
end
Now, when I check the properties of these objects:
test_obj_array(1,1).A = []
test_obj_array(1,1).B = []
test_obj_array(1,2).A = 1
test_obj_array(1,2).B = 2
...
Why is the first object in the array not constructed?
Now, it's easy to fix by adding test_obj_array(1,1) = test_class
or by modifying the properties later, but that's an easy thing to forget and a difficult thing to troubleshoot.
Note: this behavior is not seen if you pass an array of values to the constructor, as demonstrated in this MATLAB documentation.
Upvotes: 2
Views: 77
Reputation: 12693
I'm not entirely sure what's going on under the hood here to make this behavior happen. However, from the MATLAB documentation on initializing object arrays, the syntax you can use to get the behavior you want is:
test_obj_array(x,y) = test_class;
This will call the default constructor properly.
Based on the documentation, which says
When MATLAB calls a constructor with no arguments to initialize an object array, one of the following assignments occurs:
- If property definitions specify default values, MATLAB assigns these values.
- If the constructor assigns values in the absence of input arguments, MATLAB assigns these values.
- If neither of the preceding situations apply, MATLAB assigns the value of empty double (that is, []) to the property.
In your case, the second bullet point ought to apply, but isn't for some reason. I set some breakpoints inside the constructor, and when the object is initialized as an array from outside (i.e. the syntax I suggest above, that works), the default ctor is called for each non-explicitly-constructed object. When initializing the array from inside the ctor, though, the default ctor isn't being called. This is perhaps due to the expectation that each object will need to be explicitly initialized anyway (how array syntax is expected to work in the examples in the docs), so why do it twice, but... I agree with you, and I consider this a bug or at least a poor design choice by Mathworks.
On a side note, the logic you're using (that isn't working anyway) to determine the size of the array is messed up. Passing [3, 5]
gives you a 1x2
array as a result, because size(S)
is 1x2, not 3x5...
Upvotes: 1