Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[débutant objet] tableau de pointeur de fonction

47 réponses
Avatar
cyrcocq
Bonjour,

Je définis une classe qui me permet de générer des formes d'ondes (extraits
code en fin de message(toutes critiques bienvenues ;-) ))
Dans cette classe, j'ai quelques fonctions,
de type
void F0 (double);

Je veux faire un tableau de pointeurs de fonctions mais je rencontre
quelques difficultés.

J'essaie de faire un
typedef void (*fptronde) (double);

puis je fais des

fonction[0]=&onde::F0;

Mais ça ne compile pas... error C2440: '=' : impossible de convertir de
'void (__thiscall onde::* )(double)' en 'onde::fptronde'

Allors 3 questions:

comment dois-je définir mon type de pointeur sur fonction???

suis-je obligé de passer par un type que je n'utilise qu'une fois?

Les données étant dupliquées pour chaque instance de la classe, que dois-je
faire pour n'avoir qu'une instance de ce pointeur de fonction?

Merci.






class onde
{
private:

double Amp, *PAmp, Freq, *PFreq, Deph, *PDeph, Off, *POff; //Amplitude
Frequence déphasage offset (numériques fixes) et pointeurs associés.

typedef void (*fptronde) (double);

fptronde fonction [5];

void sinusoide(double);
void carree (double);
void triangulaire (double);
void montante (double);
void descendante (double);

public:

int type; //type de générateur d'onde
double sortie;
bool zero;

onde();
double CalcSortie(double);
void SetAmplitude(double);
void LieAmplitude(double&);
void SetFrequence(double);
void LieFrequence(double&);
void SetDephasage(double);
void LieDephasage(double&);
void SetOffset(double);
void LieOffset(double&);
};

void onde::sinusoide(double t)
{
sortie= *PAmp * sin( *PFreq * t + *PDeph ) + *POff;
}
(...)
onde::onde()
{
Amp=Freq=Deph=Off=0;
PAmp=&Amp;
PFreq=&Freq;
PDeph=&Deph;
POff=&Off;
type=0;

fonction[0]=&onde::sinusoide;
fonction[1]=&onde::carree;
fonction[2]=&onde::triangulaire;
fonction[3]=&onde::montante;
fonction[4]=&onde::descendante;
}

double onde::CalcSortie(double t)
{
double temp=*PFreq * t;
(*(fonction[type]))(t);
}

void onde::SetAmplitude(double A)
{
Amp=A;
PAmp=&Amp;
}
void onde::LieAmplitude(double &A)
{
PAmp=&A;
}
(...)

10 réponses

1 2 3 4 5
Avatar
Targeur fou
cyrcocq wrote:
Bonjour,

Je définis une classe qui me permet de générer des formes d'ondes ( extraits
code en fin de message(toutes critiques bienvenues ;-) ))
Dans cette classe, j'ai quelques fonctions,
de type
void F0 (double);

Je veux faire un tableau de pointeurs de fonctions mais je rencontre
quelques difficultés.

J'essaie de faire un
typedef void (*fptronde) (double);

puis je fais des

fonction[0]=&onde::F0;

Mais ça ne compile pas... error C2440: '=' : impossible de convertir de
'void (__thiscall onde::* )(double)' en 'onde::fptronde'

Allors 3 questions:

comment dois-je définir mon type de pointeur sur fonction???


typedef void (onde::*fptronde) (double);

Car un pointeur vers une fonction membre n'est pas la même chose qu'un
pointeur vers une fonction "ordinaire".

suis-je obligé de passer par un type que je n'utilise qu'une fois?


Pas compris.

Les données étant dupliquées pour chaque instance de la classe, que dois-je
faire pour n'avoir qu'une instance de ce pointeur de fonction?


Attention, il s'agit d'une définition de type "pointeur vers fonction
membre de la classe onde". Tu n'a pas d'instance de ce pointeur de
fonction mais un tableau de pointeurs vers fonctions membres qui
s'appelle fonction.

Tu peux laisser comme cela, par contre, tu manipules des données de
types pointeur sur qqchose, donc pense à faire un constructeur par
copie, à surcharger l'opérateur d'affectation.

A+
Le targeur.

Avatar
Pascal Pizeine
"cyrcocq" a écrit dans le message de news:
43329842$0$301$
Bonjour,

Je définis une classe qui me permet de générer des formes d'ondes
(extraits
code en fin de message(toutes critiques bienvenues ;-) ))
Dans cette classe, j'ai quelques fonctions,
de type
void F0 (double);

Je veux faire un tableau de pointeurs de fonctions mais je rencontre
quelques difficultés.

J'essaie de faire un
typedef void (*fptronde) (double);

puis je fais des

fonction[0]=&onde::F0;

Mais ça ne compile pas... error C2440: '=' : impossible de convertir de
'void (__thiscall onde::* )(double)' en 'onde::fptronde'

Allors 3 questions:

comment dois-je définir mon type de pointeur sur fonction???

suis-je obligé de passer par un type que je n'utilise qu'une fois?

Les données étant dupliquées pour chaque instance de la classe, que
dois-je
faire pour n'avoir qu'une instance de ce pointeur de fonction?

Merci.



Bonjour,

Ton code ressemble beaucoup à ce que l'on ferait avec du C. Tu ne profite
pas des avantages que peuvent t'offrir l'objet et le C++.
Je ne pense pas que dans ton cas le pointeur de fonction te soit utile. Un
exemble de code pourrait être le suivant :

Une classe onde générique :

class onde
{
private:
double Amp, *PAmp, Freq, *PFreq, Deph, *PDeph, Off, *POff; //Amplitude
Frequence déphasage offset (numériques fixes) et pointeurs associés.

// Une fonction virtuelle pure car tu as besoin d'une forme pour ton onde
mais tu es incapable de la définir à ce niveau
virtual void forme(double) = 0;

public:
// Le type d'onde ne sert à rien
double sortie;
bool zero;

onde();
double CalcSortie(double);
void SetAmplitude(double);
void LieAmplitude(double&);
void SetFrequence(double);
void LieFrequence(double&);
void SetDephasage(double);
void LieDephasage(double&);
void SetOffset(double);
void LieOffset(double&);
};

onde::onde()
{
Amp=FreqÞph=Off=0;
PAmp=&Amp;
PFreq=&Freq;
PDeph=&Deph;
POff=&Off;
}

double onde::CalcSortie(double t)
{
double temp=*PFreq * t;
// Ici tu utilises ta forme d'onde
forme(t);
}

void onde::SetAmplitude(double A)
{
Amp=A;
PAmp=&Amp;
}
void onde::LieAmplitude(double &A)
{
PAmp=&A;
}
(...)

Tu spécialise ensuite tes ondes, pour une sinusoide tu auras la classe
suivante :

class sinusoide : public onde
{
private:

// La fonction pour la forme de la sinusoide
virtual void forme(double);
public:
sinusoide();

(...)
}

void sinusoide::forme(double t)
{
sortie= *PAmp * sin( *PFreq * t + *PDeph ) + *POff;
}
(...)

Voila. Ca réponde pas vraiment à la question mais ca me semble plus logique
ainsi.
Sinon si tu souhaite utiliser le pointeur de fonction il faut mettre :
typedef void (onde::*fptronde) (double);

Pascal


class onde
{
private:

double Amp, *PAmp, Freq, *PFreq, Deph, *PDeph, Off, *POff; //Amplitude
Frequence déphasage offset (numériques fixes) et pointeurs associés.

typedef void (*fptronde) (double);

fptronde fonction [5];

void sinusoide(double);
void carree (double);
void triangulaire (double);
void montante (double);
void descendante (double);

public:

int type; //type de générateur d'onde
double sortie;
bool zero;

onde();
double CalcSortie(double);
void SetAmplitude(double);
void LieAmplitude(double&);
void SetFrequence(double);
void LieFrequence(double&);
void SetDephasage(double);
void LieDephasage(double&);
void SetOffset(double);
void LieOffset(double&);
};

void onde::sinusoide(double t)
{
sortie= *PAmp * sin( *PFreq * t + *PDeph ) + *POff;
}
(...)
onde::onde()
{
Amp=FreqÞph=Off=0;
PAmp=&Amp;
PFreq=&Freq;
PDeph=&Deph;
POff=&Off;
type=0;

fonction[0]=&onde::sinusoide;
fonction[1]=&onde::carree;
fonction[2]=&onde::triangulaire;
fonction[3]=&onde::montante;
fonction[4]=&onde::descendante;
}

double onde::CalcSortie(double t)
{
double temp=*PFreq * t;
(*(fonction[type]))(t);
}

void onde::SetAmplitude(double A)
{
Amp=A;
PAmp=&Amp;
}
void onde::LieAmplitude(double &A)
{
PAmp=&A;
}
(...)





Avatar
cyrcocq
"Targeur fou" a écrit
cyrcocq wrote:

Allors 3 questions:

comment dois-je définir mon type de pointeur sur fonction???


typedef void (onde::*fptronde) (double);

Car un pointeur vers une fonction membre n'est pas la même chose qu'un
pointeur vers une fonction "ordinaire".

suis-je obligé de passer par un type que je n'utilise qu'une fois?


Pas compris.
En fait, je voulais dire: dois-je vraiment définir un type sachant qu'il n'y

aura qu'un membre de la classe qui se servira de ce type?

typedef void (onde::*fptronde) (double);
fptronde fonction [5];

Les données étant dupliquées pour chaque instance de la classe, que
dois-je
faire pour n'avoir qu'une instance de ce pointeur de fonction?


Attention, il s'agit d'une définition de type "pointeur vers fonction
membre de la classe onde". Tu n'a pas d'instance de ce pointeur de
fonction mais un tableau de pointeurs vers fonctions membres qui
s'appelle fonction.
Mais? ce tableau de pointeur est bien instancié à chaque création d'un de

mes objets?
En cherchant un peu je me suis dit que je devais modifier comme ça:

static fptronde fonction [5];

Ai je raison?

De toutes façons, dans un cas comme dans l'uatre, je n'arrive pas à
effectuer mon appel!!!
fonction[type] (t);
error C2064: le terme ne correspond pas à une fonction

J'ai essayé je ne sais combien de syntaxes avec des "this" et des "onde",
avec des "::" et des "." et des "->"
Ca ne veut rien savoir!

Tu peux laisser comme cela, par contre, tu manipules des données de
types pointeur sur qqchose, donc pense à faire un constructeur par
copie, à surcharger l'opérateur d'affectation.


C'est vrai ça! J'aurais du y penser!

A+
Le targeur.


Merci


Avatar
cyrcocq
"Pascal Pizeine" a écrit

Bonjour,

Ton code ressemble beaucoup à ce que l'on ferait avec du C. Tu ne profite
pas des avantages que peuvent t'offrir l'objet et le C++.


C'est vrai, mais, je débute en C++ et encore plus en objet!
Il m'est difficile de concevoir en objet pour l'instant...
Mais je lis, je teste, j'apprends... J'y arriverais!!!

Je ne pense pas que dans ton cas le pointeur de fonction te soit utile. Un
exemble de code pourrait être le suivant :

Une classe onde générique :

class onde
{
private:
double Amp, *PAmp, Freq, *PFreq, Deph, *PDeph, Off, *POff; //Amplitude
Frequence déphasage offset (numériques fixes) et pointeurs associés.

// Une fonction virtuelle pure car tu as besoin d'une forme pour ton
onde mais tu es incapable de la définir à ce niveau
virtual void forme(double) = 0;

public:
// Le type d'onde ne sert à rien
double sortie;
bool zero;

onde();
double CalcSortie(double);
void SetAmplitude(double);
void LieAmplitude(double&);
void SetFrequence(double);
void LieFrequence(double&);
void SetDephasage(double);
void LieDephasage(double&);
void SetOffset(double);
void LieOffset(double&);
};

onde::onde()
{
Amp=FreqÞph=Off=0;
PAmp=&Amp;
PFreq=&Freq;
PDeph=&Deph;
POff=&Off;
}

double onde::CalcSortie(double t)
{
double temp=*PFreq * t;
// Ici tu utilises ta forme d'onde
forme(t);
}

void onde::SetAmplitude(double A)
{
Amp=A;
PAmp=&Amp;
}
void onde::LieAmplitude(double &A)
{
PAmp=&A;
}
(...)

Tu spécialise ensuite tes ondes, pour une sinusoide tu auras la classe
suivante :

class sinusoide : public onde
{
private:

// La fonction pour la forme de la sinusoide
virtual void forme(double);
public:
sinusoide();

(...)
}

void sinusoide::forme(double t)
{
sortie= *PAmp * sin( *PFreq * t + *PDeph ) + *POff;
}
(...)

Voila. Ca réponde pas vraiment à la question mais ca me semble plus
logique ainsi.


Je vois bien l'esprit. Effectivement ca colle bien aux notions de la POO que
j'ai pu glanner.
Mais j'ai un doute sur la méthode d'utilisation.
En effet, dans l'utilisation que je compte faire de mon "objet", la forme
d'onde est sensée pouvoir évoluer.
En gros, j'ai un ensemble de générateurs d'ondes (éventuellement avec des
interconnections) et je peux changer la forme d'onde émise par chacun de ces
générateurs sans changer leurs interconncections...
Qu'en penses tu?

Sinon si tu souhaite utiliser le pointeur de fonction il faut mettre :
typedef void (onde::*fptronde) (double);

Pascal


Avatar
Stan
"cyrcocq" a écrit dans le message de news:
43329842$0$301$
}
void onde::LieAmplitude(double &A)
{
PAmp=&A;
}
(...)


Qu'est censée faire cette méthode ?

--
-Stan

Avatar
Pascal Pizeine
"cyrcocq" a écrit dans le message de news:
4332aec2$0$307$

"Pascal Pizeine" a écrit

Bonjour,

Ton code ressemble beaucoup à ce que l'on ferait avec du C. Tu ne profite
pas des avantages que peuvent t'offrir l'objet et le C++.


C'est vrai, mais, je débute en C++ et encore plus en objet!
Il m'est difficile de concevoir en objet pour l'instant...
Mais je lis, je teste, j'apprends... J'y arriverais!!!

Je ne pense pas que dans ton cas le pointeur de fonction te soit utile.
Un exemble de code pourrait être le suivant :

Une classe onde générique :

class onde
{
private:
double Amp, *PAmp, Freq, *PFreq, Deph, *PDeph, Off, *POff;
//Amplitude
Frequence déphasage offset (numériques fixes) et pointeurs associés.

// Une fonction virtuelle pure car tu as besoin d'une forme pour ton
onde mais tu es incapable de la définir à ce niveau
virtual void forme(double) = 0;

public:
// Le type d'onde ne sert à rien
double sortie;
bool zero;

onde();
double CalcSortie(double);
void SetAmplitude(double);
void LieAmplitude(double&);
void SetFrequence(double);
void LieFrequence(double&);
void SetDephasage(double);
void LieDephasage(double&);
void SetOffset(double);
void LieOffset(double&);
};

onde::onde()
{
Amp=FreqÞph=Off=0;
PAmp=&Amp;
PFreq=&Freq;
PDeph=&Deph;
POff=&Off;
}

double onde::CalcSortie(double t)
{
double temp=*PFreq * t;
// Ici tu utilises ta forme d'onde
forme(t);
}

void onde::SetAmplitude(double A)
{
Amp=A;
PAmp=&Amp;
}
void onde::LieAmplitude(double &A)
{
PAmp=&A;
}
(...)

Tu spécialise ensuite tes ondes, pour une sinusoide tu auras la classe
suivante :

class sinusoide : public onde
{
private:

// La fonction pour la forme de la sinusoide
virtual void forme(double);
public:
sinusoide();

(...)
}

void sinusoide::forme(double t)
{
sortie= *PAmp * sin( *PFreq * t + *PDeph ) + *POff;
}
(...)

Voila. Ca réponde pas vraiment à la question mais ca me semble plus
logique ainsi.


Je vois bien l'esprit. Effectivement ca colle bien aux notions de la POO
que j'ai pu glanner.
Mais j'ai un doute sur la méthode d'utilisation.
En effet, dans l'utilisation que je compte faire de mon "objet", la forme
d'onde est sensée pouvoir évoluer.
En gros, j'ai un ensemble de générateurs d'ondes (éventuellement avec des
interconnections) et je peux changer la forme d'onde émise par chacun de
ces générateurs sans changer leurs interconncections...
Qu'en penses tu?


Tu pourrais avoir un objet générateur d'onde dont l'un des membre serait une
onde. Si tu changes de forme d'onde tu modifie cette variable. Il y a
surement plein d'autre façon de faire. Je pense qu'en POO le plus inportant
c'est de bien définir ses objets si à un moment tu te rend compte que ton
modèle est bancal, soit tu vas ajouter des rustines et obtenir une usine à
gaz, soit tu vas tout reprendre à zéro. Tu as tout intéret à passer pas mal
de temps à faire ta conception sur "papier" avant de commencer à coder.

Pascal


Sinon si tu souhaite utiliser le pointeur de fonction il faut mettre :
typedef void (onde::*fptronde) (double);

Pascal








Avatar
cyrcocq
"Stan" a écrit dans le message de news:
4332b2b2$0$20167$

"cyrcocq" a écrit dans le message de news:
43329842$0$301$
}
void onde::LieAmplitude(double &A)
{
PAmp=&A;
}
(...)


Qu'est censée faire cette méthode ?


En fait pour tous mes paramétres j'ai une variable et un pointeur.
Au départ, je lie ce pointeur à mon paramétre.
Mais je peux aussi lier ce pointeur à un autre double défini par ailleurs.
C'est l'interet de cette méthode.
Par la suite, dans mes calcul d'ondes, je n'utilise pas ma variable Amp (qui
est définie uniquement pour le cas ou l'amplitude de mon onde ne change
pas), mais *PAmp (de maniére à pouvoir utiliser un paramétre ou une sortie
d'un autre objet générateur d'onde ou autre)

Ya une erreur dans mon raisonnement?


Avatar
cyrcocq
"Pascal Pizeine" a écrit dans le message de
news: dgubqu$ga0$

En gros, j'ai un ensemble de générateurs d'ondes (éventuellement avec des
interconnections) et je peux changer la forme d'onde émise par chacun de
ces générateurs sans changer leurs interconncections...
Qu'en penses tu?


Tu pourrais avoir un objet générateur d'onde dont l'un des membre serait
une onde. Si tu changes de forme d'onde tu modifie cette variable.


Ca ressemble à ce que je tentais non?
Utiliser un indice permettant de choisir une fonction dans un tableau de
pointeur de fonctions.


Avatar
cyrcocq
"cyrcocq" a écrit>
"Targeur fou" a écrit
cyrcocq wrote:


En fait, je voulais dire: dois-je vraiment définir un type sachant qu'il
n'y aura qu'un membre de la classe qui se servira de ce type?

typedef void (onde::*fptronde) (double);
fptronde fonction [5];


A force de chercher sur internet, j'ai vu l'écriture sans typedef...
Je vais rester avec typedef.

Attention, il s'agit d'une définition de type "pointeur vers fonction
membre de la classe onde". Tu n'a pas d'instance de ce pointeur de
fonction mais un tableau de pointeurs vers fonctions membres qui
s'appelle fonction.
Mais? ce tableau de pointeur est bien instancié à chaque création d'un de

mes objets?
En cherchant un peu je me suis dit que je devais modifier comme ça:

static fptronde fonction [5];

Ai je raison?


Je me pose toujours la question...

De toutes façons, dans un cas comme dans l'autre, je n'arrive pas à
effectuer mon appel!!!
fonction[type] (t);
error C2064: le terme ne correspond pas à une fonction

J'ai essayé je ne sais combien de syntaxes avec des "this" et des "onde",
avec des "::" et des "." et des "->"
Ca ne veut rien savoir!


Toujours pas d'amélioration... J'ai pas trouvé une site sur lequel je
pourrais trouver la réponse à mon probléme. Là, j'ai vraiment besoin d'un
coup de main!


Avatar
Stan
"cyrcocq" a écrit dans le message de news:
4332c7f0$0$309$

Toujours pas d'amélioration... J'ai pas trouvé une site sur lequel je
pourrais trouver la réponse à mon probléme. Là, j'ai vraiment besoin d'un

coup de main!



Je t'ai fait un petit exemple qui n'est pas aboutit
mais qui exploite l'opérateur ( ) qui peut être utile
dans ton cas.
L'utisation du map est aussi intéressante
dans le cadre d'un système à base de menu.

C'est juste pour te donner qq idées.

--
-Stan


--------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------

#include <math.h>
#include <iostream>
#include <map>
#include <string>

class Func
{
private:
double Ampl;
public:
Func(double ampl) : Ampl(ampl) { };
double GetAmpl() { return Ampl; }
void SetAmpl(double ampl) { Ampl = ampl; };
double operator()(double t) { return Exec( t ); }
protected:
virtual double Exec(double t)=0;

};

class Sinus : public Func
{
public:
Sinus(double ampl) : Func(ampl) { };
virtual double Exec(double t);
};

double Sinus::Exec(double t)
{
return sin( t ) * GetAmpl();
}

class Log : public Func
{
public:
Log(double ampl) : Func(ampl) { };
virtual double Exec(double t);
};

double Log::Exec(double t)
{
return log(t) * GetAmpl();
}

void Show(Func* f, double t)
{
if( f == 0){
std::cout << "ERROR: unknow!" << std::endl;
return;
}

for(double x=0; x< t; x++)
std::cout << "X= " << x << ", Y= " << (*f)(x) << std::endl;


}

std::map<std::string, Func*> functions;

int main()
{
functions["sinus x 10"] = new Sinus(10);
functions["log x 20"] = new Log(20);

Show( functions["log x 20"] , 100);

//...

return 0;
}

//---------------------------------------------------------------------------


1 2 3 4 5