Как заставить matlab вызывать обычную функцию, а не метод класса, когда они перегружены?

Предположим, у меня есть объект X класса MyClass, MyClass есть метод computeи когда я звоню U = compute(X,...)Matlab автоматически вызывает метод класса. Однако на самом деле я хочу вызвать другую функцию, также называемую compute чьи параметры начинаются с MyClass возражать хотя. Как заставить matlab вызывать эту обычную функцию, а не идти в метод класса?

3 ответа

Решение

Невозможно сделать это без внесения некоторых изменений в имя или местоположение функции. Если вы проверяете порядок приоритета функций Matlab, методы всегда выполняются перед обычными внешними функциями. Ваши единственные практические варианты:

  1. Измените имя функции.
  2. Переместите тело функции в тот же скрипт, который вызывает функцию (пункт 4 в списке выше)
  3. Переместите файл.m функции в папку с именем private в той же папке, что и ваш файл скрипта (пункт 5 в списке)

ОБНОВИТЬ

Хотя это не совсем практично для небольших проектов, вы также можете захотеть рассмотреть упаковку своих функций. Хорошее обсуждение можно найти в этом посте.

Если твой compute случается, встроенный в MATLAB, вы можете использовать

builtin('compute', ...)

в противном случае, нет никакого пути - см. ответ Би.

Если вам это отчаянно нужно, то вы можете сделать что-то вроде следующего. Я настоятельно рекомендую вам не делать этого и придерживаться ответа Би. Однако иногда у человека нет выбора...

Идея состоит в том, чтобы поместить ваш экземпляр в другой класс, чтобы диспетчерская функция MATLAB не видела compute метод. Тем не менее, к вашему compute функции, упакованный экземпляр должен выглядеть так же, как и исходный экземпляр. В некоторых случаях это сложно сделать правильно, но часто достаточно следующего:

classdef Wrapper

    properties (Access = 'private', Hidden = true)
        core = [];
    end

    methods

        function this = Wrapper(core)
            this.core = core;
        end

        function varargout = subsref(this, S)
            if nargout > 0
                varargout = cell(1, nargout);
                [varargout{:}] = subsref(this.core, S);
            else
                subsref(this.core, S);
            end
        end

    end

end

Этот класс оборачивает экземпляр другого класса и делегирует весь доступ на чтение к обернутому экземпляру.

Например, если у вас есть файл с именем TestClass.m:

classdef TestClass

    properties
        name = '';
    end

    methods
        function this = TestClass(name)
            this.name = name;
        end

        function compute(this)
            fprintf('Instance method! My name is "%s".\n', this.name);
        end
    end

end

И функция compute.m:

function compute(x)
    fprintf('Regular function! My name is "%s".\n', x.name);
end

Тогда это работает так:

>> t = TestClass('t');
>> s = struct('name', 's');
>> compute(t)
Instance method! My name is "t".
>> compute(s)
Regular function! My name is "s".
>> w = Wrapper(t);
>> compute(w)
Regular function! My name is "t".

В зависимости от того, что compute функция делает с вашим экземпляром, вам может понадобиться добавить дополнительные "специальные" функции к Wrapper (например subsasgn). Также обратите внимание, что это сломается, если compute делает некоторую метаклассическую магию.

Другие вопросы по тегам