2013-08-02 60 views
0

獲得一個處理對象的基礎的工作空間的名稱,以便我有一個類從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時,它將返回'obj',因爲它在回調定義中定義。但是,如果我通過終端呼叫callback_test,它會返回適當的變量名稱(結果合理,但這不是我想要的)。一個例子如下所示:

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

所以我的問題是:如何能夠獲得變量名,優選在構造,並且如果沒有,那麼我怎樣才能得到它通過回調而無需使用所述終端。

+0

就想出了一個主意:你可以潛在地使用'whos',然後找到類類型你感興趣的所有變量名的時候,你可以'assignin'到調用工作區並使用'eq'將每個變量與'obj'進行比較以找到正確的名稱。我會稍後看看它是否有效。 – Justin

+0

好吧,我的評論是錯誤的,因爲你不能在嵌套函數中使用'assignin',所以現在我回到了原點。 – Justin

+0

我在這裏展示如何檢索賦值變量名稱:http://stackoverflow.com/questions/17554012/in-matlab-is-it-possible-to-check-if-an-object-already-exists-before-創建-A/17601143#17601143。 – Oleg

回答

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 

然後讓你的構造私人。

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)