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

できればコンストラクターでオブジェクトのワークスペース名を取得したいと思います。オブジェクトの作成後まで名前が割り当てられるかどうかわからないため、これが可能かどうかはわかりません。その場合は、コールバックを介して取得したいと思います。objGUI はありますが、ハンドルを適切に渡す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>> 

したがって、私の質問は、できればコンストラクターで変数名を取得するにはどうすればよいですか。そうでない場合は、ターミナルを使用せずにコールバックを介して取得するにはどうすればよいですか。

4

2 に答える 2

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

何らかの理由で (いくつか考えられる)、それぞれのインスタンスが 1 つだけ存在するようにしたい場合は、クラス内でassignedNamestatic を使用して既存のオブジェクトのリストを維持し、静的ファクトリ メソッドを使用して作成することができます。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

次に、コンストラクターを非公開にします。

于 2013-08-02T23:05:40.173 に答える
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)
于 2013-08-03T21:02:48.927 に答える