web-dev-qa-db-fra.com

Pointeur d'appel C ++ vers la fonction membre

J'ai une liste de pointeurs vers les fonctions membres mais j'ai du mal à appeler ces fonctions ... quelle est la syntaxe appropriée?

typedef void (Box::*HitTest) (int x, int y, int w, int h);

for (std::list<HitTest>::const_iterator i = hitTestList.begin(); i != hitTestList.end(); ++i)
{
    HitTest h = *i;
    (*h)(xPos, yPos, width, height);
}

Im également essayer d'ajouter des fonctions membres ici

std::list<HitTest> list;

for (std::list<Box*>::const_iterator i = boxList.begin(); i != boxList.end(); ++i)
{
    Box * box = *i;
    list.Push_back(&box->HitTest);
}
27
ThingWings

Les pointeurs vers des membres non statiques sont une bête unique avec une syntaxe unique.

Ces fonctions doivent être fournies avec un pointeur this, vous devez donc avoir le pointeur Box à portée de main qui sera utilisé comme this.

(box->*h)(xPos, yPos, width, height);
32
Drew Dormann

L'appel d'une fonction membre via un pointeur vers une fonction membre a une syntaxe particulière:

(obj.*pmf)( params );   //  Through an object or reference.
(ptr->*pmf)( params );  //  Through a pointer.

Bien que ->* peut être écrasé, il n'est pas dans les itérateurs de bibliothèque standard (probablement parce qu'il nécessiterait des écrasements pour chaque type de fonction possible). Donc, si tout ce que vous avez est un itérateur, vous devrez le déréférencer et utiliser le premier formulaire:

((*iter).*pmf)( params );

D'un autre côté, l'itération sur un pointeur vers les membres eux-mêmes n'a pas ce problème:

(objBox.*(*i))( params );   //  If objBox is an object
(ptrBox->*(*i))( params );  //  If ptrBox is a pointer

(Je ne pense pas que vous ayez besoin des parenthèses autour du *i, mais le pointeur sur la syntaxe des membres est déjà assez spécial.)

10
James Kanze

De ma réponse "primée" ;-) sur les délégués (disponible sur https://stackoverflow.com/questions/9568150/what-is-a-c-delegate/9568226#9568226 ):

Tapez le pointeur sur la fonction membre comme ceci:

typedef void (T::*fn)( int anArg );

Déclarez-en un comme ceci:

fn functionPtr = &MyClass::MyFunction

Appelez ça comme ceci:

(MyObject.*functionPtr)( argument );
8
Grimm The Opiner

Votre tentative d'obtenir un pointeur de fonction membre à travers un objet trahit un malentendu. Les pointeurs de fonction membre n'incluent pas de pointeur sur l'objet sur lequel vous les appelez. Vous devez fournir un tel pointeur au moment de l'appel.

Comme beaucoup l'ont souligné, la syntaxe d'un appel de fonction membre est soit:

 obj.*funcptr(args);

ou

 objptr->*funcptr(args);

Dans l'exemple que vous avez donné, il semble que vous ayez vraiment besoin d'une fonction virtuelle. Vous avez une opération standard (détecter si un objet recoupe ou non une boîte) qui doit être appelée sur de nombreux types d'objets différents, dont le type ne peut pas être connu au moment de la compilation. Il s'agit d'un travail qui est conçu pour les fonctions virtuelles.

1
Omnifarious