In pratica ho una classe con una funzione a cui voglio applicare una
funzione di una classei rootsfinder. Devo trovare gli zeri di una
funzione membro.
Aggiungo la classe dei solvers
#include "rootfinder.."
la classe in cui sta la funzione di cui voglio trovare gli zeri č
in a e si chiama f.
class a
{
...
double soluzione();
...
double f(double x);
..
..};
l'implementazione di a::soluzione() č
double a::soluzione ()
{
solvers mys;
mys.F=&a::f;
return mys.solve()
}
La classe rootfinder ha un puntatore ad un funzione (pubblico)
double (*F)(double x);
Errore 2440 .VIsualstudio 2005 mi dice di usare &a::F
Ho cercato di capire, ma invano.
grazie.
Correggetemi se sbaglio: non puoi avere puntatori a mebri di funzione che
non siano statici per il semplice fatto che non potresti sapere a quale
istanza di quale oggetto appartiene. So che si puo' aggirare questo problema
in qualche modo ma non sono ancora cosi' esperto...
So pero' che puoi risolvere il problema passando il puntatore alla funzione
come parametro della solve();
GuGu wrote:
> Correggetemi se sbaglio: non puoi avere puntatori a mebri di funzione
> che non siano statici per il semplice fatto che non potresti sapere a
> quale istanza di quale oggetto appartiene.
In teoria puoi averne, ma non è una buona idea. In ogni caso non vengono
trattati come puntatori a funzione «normali» e non sono intercambiabili.
Se possibile, è meglio passare puntatori o riferimenti a un oggetto e da
quello tirar fuori la funzione.
Qui c'è una buona pagina sull'argomento:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html
> So che si puo' aggirare
> questo problema in qualche modo ma non sono ancora cosi' esperto...
Io, quando dovevo passare un puntatore a funzione alla GSL (che è
scritta in C e mi autorizza a passare un puntatore a void come parametro
alla funzione), ho usato il seguente trucco: siccome le funzioni
statiche di un oggetto sono trattate come funzioni simili al C (di
solito almeno), basta definire due funzioni:
class Pippo {
[...]
double toSolve( double );
static double toSolve_static( double x, void* obj )
{ return static_cast<Pippo*>(obj)->toSolve(x); }
[...]
};
Oggi, che ne so di più, mi farei un piccolo wrapper, probabilmente con
oggetti-funzione (i functor hanno un nome in italiano?), per evitare di
impastarmi con puntatori a void.
Ciao,
- -Federico
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org
iD8DBQFIfIuDBIpu+y7DlLcRAsM0AJwK8lqy/BuE4aRn29kdFvOXCSqVqACfaiOQ
Xbgxcax26MRTagdXAGCDc6U=
=uC1w
-----END PGP SIGNATURE-----
Grazie mille. Si i functor sono l'ideale ..vediamo un po se ci riesco.
On Tue, 15 Jul 2008 13:35:31 +0200, Federico Zenith
<zen...@mpiDASHmagdeburgDOTmpg.de> wrote:
belten...@quipo.it wrote:
> Cio io dovre mettere nella mia classe
> static double toSolve_static( double x, void* obj )
>> { return static_cast<Miaclasse*>(obj)->toSolve(x); }
> Per cosa sta obj?
È il puntatore all'oggetto che contiene la funzione da risolvere. È un
puntatore a void perché il C non ha la minima idea di cosa sia una
classe, allora gli passiamo un indirizzo di memoria grezzo che
convertiremo più avanti.
> Se io hola funzione brent che prende un double come guess e
> double(*f)(double)
> brent(guess,to_solve_static( ?????))
Suppongo che tu stia usando la GSL. Quello che devi fare è allocare un
risolutore Brent, configurare una struttura gsl_function, e passare
quest'ultima (che contiene un puntatore alla tua funzione statica) al
risolutore.
Pippo oggettoConFunzioneDaRisolvere;
// esiste "static double Pippo::funzioneStatica(double, void*)"
// per come definirla vedi il mio post precedente
gsl_function F;
F.function = &Pippo::funzioneStatica;
F.params = &oggettoConFunzioneDaRisolvere;
T = gsl_root_fsolver_brent;
s = gsl_root_fsolver_alloc (T);
gsl_root_fsolver_set (s, &F, x_lo, x_hi);
A questo punto puoi far partire il risolutore s, vedi i dettagli sul
sito della GSL, per esempio questa pagina di esempi:
http://www.gnu.org/software/gsl/manual/html_node/Root-Finding-Examples.html
Il codice che ne esce è orrendo, ed è fondamentalmente perché si cerca
di far fare al C quello che è un lavoro da C++... ma la GSL è in C e non
c'è niente da fare (a parte magari riscriverla :-).
> Sono alle prime armi.
Ci sono passato anch'io... :-)
Ciao,
- -Federico
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org
iD8DBQFIf3DLBIpu+y7DlLcRAhlvAJ42E06q8KT/2yrHukAmXJO4F5lm9QCgpI7/
Dp5RTO7l9hQTXSfzqZDM1uI=
=Xf9t
-----END PGP SIGNATURE-----