所以我有一个继承自handle
超类的类:
classdef testClass < handle
properties(Access = private)
handles_gui;
end
methods(Access = public)
function obj = testClass
% Preferably like to get inputname here
obj.handles_gui = obj.init_gui();
end
function callback_test(obj,hObject,eventdata)
disp(inputname(1));
end
end
methods(Access = private)
function handles_gui = init_gui(obj)
handles_gui.figure = figure( ...
'Tag', 'figure', ...
'Units', 'characters', ...
'Position', [50 35 167 25]);
handles_gui.button_left = uicontrol( ...
'Parent', handles_gui.figure, ...
'Units', 'characters', ...
'Position', [41 1.2 8 1.8], ...
'String', 'Test', ...
'Callback', @(hObject,eventdata) callback_test(obj,hObject,eventdata));
end
end
end
我希望最好在构造函数中获取对象的工作空间名称。不确定这是否可行,因为我不确定在创建对象之前是否分配了名称。如果是这样,那么我想通过回调获得它。我有一个gui,但为了正确传递obj
句柄,我必须通过在obj
函数中传递init_gui
来定义回调。这意味着当按下按钮时为inputname
调用callback_test
时,它会返回'obj'
,因为它在回调定义中定义。但是,如果我通过终端呼叫callback_test
,它会返回正确的变量名称(结果有意义,但它不是我想要的)。示例如下所示:
EDU>> test = testClass;
obj (this was called by clicking on the button)
EDU>> test.callback_test
test
EDU>>
所以我的问题是:如何获取变量名,最好是在构造函数中,如果没有,那么如何通过回调获取它而不必使用终端。
答案 0 :(得分:0)
如果您需要知道对象的指定名称,那么最好将其作为构造函数调用约定的显式部分。例如:
function obj = testClass(assignedName_input)
obj.assignedName = assignedName_input;
obj.handles_gui = obj.init_gui();
end
然后,该类的使用更改为:
anyVariableName = testClass('test'); %Replaces "test = testClass();". This separates the assigned name from the named used to keep track of it in the calling function.
或者,如果您稍后决定在阵列
中同时想要其中的5个for ix = 1:5
arrayOfObjects{ix} = testClass(['test_' num2str(ix)]); %This is not possible if you only look at the assigned variable name.
end
如果由于某种原因(我可以想到一些)你想确保每个assignedName
只有一个实例存在,你可以在类中使用静态containers.Map
来维护现有对象的列表,以及用于创建它们的静态工厂方法。 (我很确定这是“工厂方法设计模式”。)
例如,添加:
properties(Access = private, Static = true)
existingInstancesMap = containers.Map('keyType','char','valueType','any');
end
methods(Access = public, Static = true)
function mappedInstance = getInstance(assignedName);
if ~existingInstancesMap.isKey(assignedName) %If no mapped instance exists
existingInstancesMap(assignedName) = testClass(assignedName); %Then make one and map it.
end
mappedInstance = existingInstancesMap(assignedName); %Return the mapped instance
end
然后将您的构造函数设为私有。
答案 1 :(得分:0)
嗯,这只是因为其他人偶然发现了这个问题。我解决了它:
classdef testClass < handle
properties(Access = private)
handles_gui;
end
methods(Access = public)
function obj = testClass
% Preferably like to get inputname here
obj.handles_gui = obj.init_gui();
end
end
methods(Access = private)
function handles_gui = init_gui(obj)
handles_gui.figure = figure( ...
'Tag', 'figure', ...
'Units', 'characters', ...
'Position', [50 35 167 25]);
handles_gui.button_left = uicontrol( ...
'Parent', handles_gui.figure, ...
'Units', 'characters', ...
'Position', [41 1.2 8 1.8], ...
'String', 'Test', ...
'Callback', @(hObject,eventdata) callback_test(obj,hObject,eventdata));
end
function callback_test(obj,hObject,eventdata)
basevars = evalin('base','whos');
testClassvars = basevars(strcmp({basevars.class},class(obj)));
found = false;
for i = 1:length(testClassvars)
if(eq(evalin('base',testClassvars(i).name),obj))
found = true;
disp(['Name is: ' testClassvars(i).name]);
end
end
if(~found)
disp('Handle has been deleted');
end
end
end
end
这是我想要的功能;诀窍是使用evalin
来访问基础工作区中同一类的对象。我以为我需要使用assignin
来做这件事但是错了。实现这样的事情是否有利是一个不同的问题,但它最终是我想要做的,所以对于想要做类似事情的其他人来说也是如此。
输出:
EDU>> a = testClass
a =
testClass handle with no properties.
Methods, Events, Superclasses
EDU>> b = testClass
b =
testClass handle with no properties.
Methods, Events, Superclasses
Name is: b (after clicking on the button)
Name is: a (after clicking on the button)