Si supponga di avere un oggetto X
della classe MyClass
. MyClass
ha un metodo compute
e quando chiamo U = compute(X,...)
, matlab chiama automaticamente il metodo di classe. Tuttavia, quello che voglio veramente è chiamare un'altra funzione chiamata anche compute
i cui parametri iniziano con un oggetto MyClass
. Come faccio a forzare MATLAB a chiamare questa funzione regolare piuttosto che entrare nel metodo di classe?Come forzare MATLAB a chiamare una funzione regolare piuttosto che un metodo di classe quando sono sovraccarichi?
risposta
Non v'è alcun modo per farlo senza fare alcuni cambiamenti sia a nome o la posizione della funzione. Se si controlla Matlab's function precedence order, i metodi vengono sempre eseguiti prima delle normali funzioni esterne. Le tue uniche opzioni pratiche sono:
- Modificare il nome della funzione.
- Spostare il corpo della funzione per lo stesso script che chiama la funzione (voce 4 nella lista di cui sopra)
- spostare il file .m della funzione in una cartella denominata
private
nella stessa cartella del file di script (punto 5 all'ordine l'elenco)
UPDATE
anche se non è molto pratico per i piccoli progetti, si può anche voler guardare in packaging your functions. Una buona discussione può essere trovata in this SO post.
Il problema è che anche io cambio il nome della funzione in ' compute2', matlab prova ancora a chiamare il metodo class e finisce con la segnalazione di un errore poiché 'compute2' non è definito in' MyClass' ... – OneZero
in realtà se hai rinominato la funzione regolare come 'compute2' verrà chiamato correttamente (I appena provato in R2013a) – Amro
@OneZero Ricorda che è necessario modificare sia il nome della funzione che il nome del file contenente quella funzione. Quindi, per esempio, finirai con 'function x = compute2 (obj)' nel file 'compute2.m'. – Bee
Se il compute
capita di essere un incorporato MATLAB, è possibile utilizzare
builtin('compute', ...)
in caso contrario, non c'è modo - vedere la risposta di Bee.
Buon punto. Ho appena dato per scontato che la sua funzione 'compute' accetta l'oggetto personalizzato come primo parametro, non è una funzione incorporata. – Bee
@Acqua: vero. Con ogni probabilità il PO non ha a che fare con un builtin. Ma qualcun altro potrebbe: p –
Se hai un disperato bisogno di questo, allora puoi fare qualcosa come il seguente. Vi suggerisco caldamente di non farlo e di seguire la risposta di Bee. Tuttavia, a volte non si ha scelta ...
L'idea è di avvolgere l'istanza in un'altra classe in modo che la distribuzione delle funzioni di MATLAB non visualizzi il metodo compute
. Tuttavia, per la tua funzione compute
, l'istanza avvolta deve apparire uguale all'istanza originale. Questo è difficile da ottenere, in alcuni casi, ma spesso il seguente è sufficiente:
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
Questa classe avvolge un'istanza di un'altra classe e delega tutto accesso in lettura all'istanza avvolto.
Ad esempio, se si dispone di un file chiamato 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
E una funzione compute.m
:
function compute(x)
fprintf('Regular function! My name is "%s".\n', x.name);
end
Allora funziona così:
>> 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".
A seconda di cosa la funzione compute
non funziona con la tua istanza ght ha bisogno di aggiungere ulteriori funzioni "speciali" a Wrapper
(ad es. subsasgn
). Si noti anche che questo si interromperà se compute
esegue un metaclasse-magic.
alcun motivo per cui entrambe le versioni non sono metodi membri? potresti anche rendere la funzione esterna un metodo statico della classe, così viene chiamato in modo diverso: 'MyClass.compute (x)' vs. 'compute (x)' – Amro