Passing options from subclass constructor to superclass?

28 ビュー (過去 30 日間)
David Cardinal
David Cardinal 2021 年 1 月 14 日
コメント済み: David Cardinal 2021 年 1 月 15 日
I really like the new "arguments" way to pass values, including optional values. However, one really nice feature of the (old?) varargin approach was that you could just pass the whole thing along. But with arguments, if I have a subclass that only needs a couple options and is happy to pass the rest to its superclass, I don't see a great way to do that. I've found that I need to specifically implement every option and pass them specifically. I'm probably missing something, but would love to learn what. Thanks! -- David
  5 件のコメント
Luna
Luna 2021 年 1 月 15 日
Did you try inputparser?
David Cardinal
David Cardinal 2021 年 1 月 15 日
We have been using inputparser, but I really like the (newer?) arguments syntax as I think it both easier to write & read. This is the first glitch I've run into with it. Below is an example. This is a function in a sub-class that takes some options and then calls the superclass version of the function. I'd like to simply be able to pass along the options structure
function ourPicture = TakePicture(obj, aCIScene, intent, options)
arguments
obj;
aCIScene;
intent;
options.numHDRFrames = 3;
options.numBurstFrames = 3;
options.imageName char = '';
options.reRender (1,1) {islogical} = true;
end
...
ourPicture = TakePicture@ciCamera(obj, aCIScene, intent, options);;
end
And here is the method in the super-class (which can also be called directly, so I assume needs to support a similar function templae:
function ourPicture = TakePicture(obj, aCIScene, intent, options)
%TakePicture Main function telling us to create a photo
arguments
obj;
aCIScene;
intent;
options.numHDRFrames = 3;
options.imageName char = '';
options.reRender (1,1) {islogical} = true;
options.expTimes = [];
end
...
The call from the sub-class fails with the below error. The only way I've figured out to get it to work is to manually recreate the A/V pairs and pass them, which seems pretty ugly:
Invalid argument at position 4. Function requires exactly 3 positional input(s).
ourPicture = TakePicture@ciCamera(obj, aCIScene, intent, options); %'reRender', options.reRender);

サインインしてコメントする。

採用された回答

Matt J
Matt J 2021 年 1 月 15 日
編集済み: Matt J 2021 年 1 月 15 日
Can't you just convert the options structure back to a cell array of name value pairs and use that to call the super class constructor? Using the attached function struct2pairs, this would be
function ourPicture = TakePicture(obj, aCIScene, intent, options)
arguments
obj;
aCIScene;
intent;
options.numHDRFrames = 3;
options.numBurstFrames = 3;
options.imageName char = '';
options.reRender (1,1) {islogical} = true;
end
...
varargin=struct2pairs(options);
ourPicture = TakePicture@ciCamera(obj, aCIScene, intent, varargin{:});;
end
  4 件のコメント
David Cardinal
David Cardinal 2021 年 1 月 15 日
BTW, it turns out that I'd found a built-in function, namedargs2cell(), that does a very similar thing to struct2pairs, but I hadn't made the connection to using it with varargin. I think it also works when used with your sample code. Thanks again!
David Cardinal
David Cardinal 2021 年 1 月 15 日
Another handy feature for arguments is the .?<classname> option, which automatically generates a structure with properties from <classname> that might have been passed in, which can in turn be passed to namedargs2cell (or struct2pairs) and in turn as a "varargin" parameter to that class.
Overall, I'm liking this approach better than inputparser(), especially when created classes and sub-classes with lots of optional parameters.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeArgument Definitions についてさらに検索

製品


リリース

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by