在构造函数中获取句柄对象的基工作区名称



所以我有一个从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句柄,我必须通过在init_gui函数中传递obj来定义回调。这意味着当按下按钮时为callback_test调用inputname时,它将返回'obj',因为它是在回调定义中定义的。但是,如果我通过终端调用callback_test,它会返回正确的变量名(结果是有意义的,但这不是我想要的)。示例如下:

EDU>> test = testClass;
obj (this was called by clicking on the button)
EDU>> test.callback_test
test 
EDU>> 

所以我的问题是:我如何获得变量名,最好是在构造函数中,如果没有,那么我如何在不使用终端的情况下通过回调获得它。

如果您需要知道对象的指定名称,那么最好将其作为构造函数调用约定的显式部分。例如:

        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

然后让你的构造函数私有化。

好吧,这只是为了防止其他人偶然发现这个问题。我用解决了这个问题

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

这就是我想要的功能;诀窍是使用CCD_ 11来访问基本工作空间中的同一类的对象。我以为我需要使用assignin来做这件事,但我错了。实现这样的东西是否好是另一个问题,但这最终是我想做的,所以这是给其他想做类似事情的soemone的。

输出:

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)

最新更新