Pointer de fonction

Résolu
S e e D Messages postés 6 Date d'inscription mercredi 2 février 2005 Statut Membre Dernière intervention 21 février 2008 - 19 févr. 2008 à 16:28
S e e D Messages postés 6 Date d'inscription mercredi 2 février 2005 Statut Membre Dernière intervention 21 février 2008 - 21 févr. 2008 à 14:21
Bonjour,

J'ai un problème de syntaxe lors d'un appel d'un pointeur de fonction.
En gros j'ai le code suivant (qui est pas très joli mais j'ai pas beaucoup le choix) :

//fichier Cb.h----------------------------------------------
namespace A{class CA;};
namespace B
{class CB{
    public:
        CB();
        ~CB(){};
        //A::CA *myCA;
        int ((A::CA::*DoSomething)(int));
  };
}

//fichier Cb.cpp----------------------------------------------
#include "Cb.h"
using namespace B;
CB::CB(){}

void CB::setcbDoSomething( int (A::CA::*func)(int)){
    this->DoSomething = func;}

//fichier Ca.h----------------------------------------------
namespace A
{class CA{
    public:
        CA();
        ~CA(){};
        B::CB *myCB;
        int DoSomething(int toto);
    };
}

/fichier Ca.cpp----------------------------------------------
#include "Ca.h"
using namespace A;
CA::CA(){
    myCB = new B::CB();
    myCB->DoSomething = &CA::DoSomething;}

int CA::DoSomething(int toto){
    std::cout << "doing something in A" << std::endl;
    return 1;}

//Et mon main()----------------------------------------------
#include "Ca.h"
int main()
{
    A::CA *myCA = new A::CA();
    B::CB *tmpCB = myCA->myCB;
    *(tmpCB->DoSomething)(5);
    return 0;
}

Mon problème est sur cette ligne en rouge *(tmpCB->DoSomething)(5);
je ne sais pas comment l'écrire correctement pour que l'appel soit correcte.
j'ai essayé tmpCB->(*DoSometing)(5)
                tmpCB->DoSomething(5)
                *(tmpCB->DoSomething)(5)
et encore quelques autres mais sans résultat. j'ai soit une erreur C2064 : le terme ne correspond pas à une fonction qui prend 1 argument
ou une erreur C2059 erreur de syntaxe :'(' qui entraine tout plein d'erreur a la suite de cette ligne.

Merci d'avance pour vos réponses.

6 réponses

cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
19 févr. 2008 à 17:46
En fait ta fonction DoSomething est membre de classe donc de convention d'appel __thiscall (ie le compilateur lui passe implicitement comme premier argument un pointeur sur une instance de classe utilisée sous la forme this dans la fonction).
Donc pour utiliser le pointeur sur fonction il faut spécifier une instance, par exemple ceci compile :
(myCA->*(tmpCB->DoSomething))(5);
attention aux parenthèses, nécessaires à cause des priorités d'opérateurs.
3
cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
21 févr. 2008 à 14:06
Ceci compile chez moi :
class

CA;
class

CB{

public:CB(CA* _pA){pA=_pA;};

~CB(){};

CA* pA;

int ((CA::*DoSomething)(
int));

void setcbDoSomething(
int (CA::*func)(
int));

static
void DoSomethingToo(
void* lpParameter);};

void

CB::setcbDoSomething(
int (CA::*func)(
int)){

this->DoSomething = func;}
void

CB::DoSomethingToo(
void* lpParameter){CB *local = (CB*) lpParameter;

(local->pA->*(local->DoSomething))(3);}

 

class

CA{

public:CA();

~CA(){};

CB *myCB;

int DoSomething(
int toto);};

 

CA::CA(){

myCB =

new CB(
this);myCB->DoSomething = &CA::DoSomething;}

int

CA::DoSomething(
int toto){std::cout <<

"doing something in A" << std::endl;

return 1;}
3
S e e D Messages postés 6 Date d'inscription mercredi 2 février 2005 Statut Membre Dernière intervention 21 février 2008
20 févr. 2008 à 09:44
Effectivement ca marche bien mieux. Merci pour ton aide Juju.

Seulement, je me rend compte que j'ai un peut trop simplifié mon exemple (bien que celui ci m'aidera). En fait j'appel mon pointer de fonction a l'interieur de CB dans un thread. Le code devient celui ci :

--Cb.h-------------------------------------
namespace A{class CA;};
namespace B
{class CB {
    public:
        CB();
        ~CB(){};
        int ((A::CA::*DoSomething)(int));
        static void DoSomethingToo(LPVOID lpParameter);
    };
}

--Cb.cpp-----------------------------------
#include "Cb.h"
using namespace B;
CB::CB(){
    std::cout << "CB constructed" << std::endl;
    DWORD threadID;
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DoSomethingToo, this, 0, &threadID);}

static void CB::DoSomethingToo(LPVOID lpParameter){
    B::CB *local = (B::CB*) lpParameter;
   (* (local->DoSomething))(3);}

Mon 'local' est en fait un pointeur vers mon this que je ne peux pas appeler car je suis dans une fonction static. Donc en fait l'object de plus haut niveau est mon 'local' ?! Dans ce cas je n'arrive plus a appeller mon pointeur de fonction car je n'ai plus l'instance (myCA).

J'ai essayé de passer un pointeur de myCA dans myCB, mais comme je peux pas include mutuellement les headers des 2 class le pointeur de myCA que je passe a myCB ne peux etre utiliser correctement car myCB ne connais pas les fonction de la class myCA.

Je commence a perdre pieds
0
cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
20 févr. 2008 à 17:31
Je ne comprends pas très bien pourquoi tu ne peux pas inclure de pointeur CA* dans CB; ceci ne marche pas?
class CA;
class CB{CA* pCA;};

sinon l'inverse :
class CB;
class CA{...};
class CB{...};
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
S e e D Messages postés 6 Date d'inscription mercredi 2 février 2005 Statut Membre Dernière intervention 21 février 2008
21 févr. 2008 à 10:01
oui voila c'est ce que j'ai essayé de faire. Je récupere bien le pointer, quand je veux faire des appels dessus intellisense me donne bien les membres de la classe CA mais quand je compile le compilo me retourne une erreur :
error C2027: utilisation du type non défini 'A::CA' alors que la classe CA est déclarée comme le premier bout de code que tu as fait avec le namespace en plus.

En faisant l'inverse je ne peux pas construire  myCB dans CA car 'la classe n'a aucun constructeur'

J'ai l'impression que cette architecture est trop 'crade' pour permettre un dialogue correcte.

Merci encore Juju pour prendre un peut de temps pour regarder ca :)
0
S e e D Messages postés 6 Date d'inscription mercredi 2 février 2005 Statut Membre Dernière intervention 21 février 2008
21 févr. 2008 à 14:21
(local->pA->*(local->DoSomething))(3);



ah ouai ! j'aurais jamais penser a l'ecrire comme ca.
J'aurais jamais trouvé ca seul. Je suis pas au top pour les pointeurs de fonction encore ^^

Merci beaucoup Juju. Comme un dit, tu roxx !
0
Rejoignez-nous