2013-07-10 7 views
5

Załóżmy, że mam obiekt X klasy MyClass. MyClass ma metodę compute, a gdy zadzwonię pod numer U = compute(X,...), program matlab automatycznie wywoła metodę klasy. Jednak tak naprawdę chcę wywołać inną funkcję o nazwie compute, której parametry zaczynają się od obiektu MyClass. Jak zmusić matlab do wywoływania tej zwykłej funkcji, a nie do metody klasowej?Jak zmusić matlab do wywoływania zwykłej funkcji, a nie metody klasy, gdy są przeciążone?

+1

dowolny powód, dlaczego obie wersje nie są metodami członków? możesz również uczynić funkcję zewnętrzną statyczną metodą klasy, w ten sposób nazywa się ją inaczej: 'MyClass.compute (x)' kontra 'compute (x)' – Amro

Odpowiedz

6

Nie można tego zrobić bez wprowadzania pewnych zmian w nazwie lub lokalizacji funkcji. W przypadku sprawdzania Matlab's function precedence order metody zawsze działają przed normalnymi funkcjami zewnętrznymi. Twoje jedyne praktyczne opcje to:

  1. Zmień nazwę funkcji.
  2. Przesuń ciało funkcja do tego samego skryptu, który jest wywołanie funkcji (punkt 4 na liście powyżej)
  3. Przenieś plik .m z funkcji w folderze o nazwie private w tym samym folderze co plik skryptu (pozycja 5 na lista)

UPDATE

Chociaż nie bardzo praktyczne dla mniejszych projektów, można również zajrzeć do packaging your functions. Dobrą dyskusję można znaleźć w this SO post.

+0

Problem polega na tym, że nawet ja zmieniam nazwę funkcji na ' compute2', matlab nadal próbuje wywołać metodę klasy i zakończył zgłaszanie błędu, ponieważ 'compute2' nie jest zdefiniowany w' MyClass' ... – OneZero

+0

w rzeczywistości, jeśli zmieniono nazwę zwykłej funkcji na "compute2", to zostanie ona nazwana poprawnie (I po prostu wypróbowałem to w R2013a) – Amro

+0

@OneZero Pamiętaj, że musisz zmienić zarówno nazwę funkcji, jak i nazwę pliku zawierającego tę funkcję. Na przykład skończysz z 'function x = compute2 (obj)' wewnątrz pliku 'compute2.m'. – Bee

2

Jeśli Twój compute dzieje się wbudowane MATLAB, można użyć

builtin('compute', ...) 

inaczej, nie ma mowy - patrz odpowiedź Bee.

+0

Dobra uwaga. Właśnie założyłem, ponieważ jego funkcja "compute" akceptuje obiekt niestandardowy jako pierwszy parametr, nie jest to funkcja wbudowana. – Bee

+1

@Bee: true. Najprawdopodobniej OP nie zajmuje się wbudowanym. Ale ktoś inny mógłby: p –

2

Jeśli bardzo tego potrzebujesz, możesz zrobić coś takiego. Zdecydowanie sugeruję, abyś tego nie robił i trzymaj się odpowiedzi Bee. Jednak czasami nie ma się wyboru ...

Chodzi o to, aby owinąć instancję w inną klasę, aby funkcja wysyłania funkcji MATLAB nie widziała metody compute. Jednak do funkcji compute, opakowana instancja musi wyglądać tak samo jak oryginalna instancja. Jest to trudne, aby uzyskać prawo w niektórych przypadkach, ale często po to wystarczy:

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 

Ta klasa jest zawijany wystąpienie innej klasy i delegatów wszystkim dostęp do odczytu zawiniętego instancji.

Na przykład, jeśli masz plik o nazwie 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 

i funkcję compute.m:

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

Wtedy to działa tak:

>> 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". 

W zależności od tego, co funkcja compute działa z Twoją instancją Trzeba dodać dodatkowe "specjalne" funkcje do Wrapper (np. subsasgn). Zauważ, że to się zepsuje, jeśli compute zrobi magię metaklasu.

+0

+1. Dobra praca dochodzeniowa! – Bee

+0

to ostatnie 'doStuff (w)' powinno być 'compute (w)'. +1 dla obejścia, ale ja też nie polecam używania tego w prawdziwym kodzie :) – Amro

+0

@Amro: Dzięki, naprawione. To pozostał po moim kodzie prób i błędów. –

Powiązane problemy