2016-10-16 1 views
-1

Je suis tout à fait nouveau pour C++, et probablement j'avais des problèmes naïfs. Je sais qu'il y a d'autres questions smilar, mais qui sont liées à (semble-t-il) un problème plus complexe que le mien. J'essaie de faire un firmware pour Arduino, en utilisant C++ et je me suis blessé avec les erreurs de surcharge.C++ base de: type de fonction non résolue surcharge

Je le code définit dans un fichier cpp:

void class1::functionA(void) 
{ 
    object2.functionOfClass2(class1::functionB); 
} 

Le Class1 est initialisé:

class class1 
{ 
public: 
void functionA(void); 
void functionB(void); 
private: 
} 

Et dans la compilation donne

no matching function for call to 'class2::functionOfClass2(<unresolved overloaded function type>)' 

Traduire en la pratique:

dans mon code J'utilise la bibliothèque de fil dans une fonction de membre du Class1 pour une bibliothèque Arduino, où, dans l'exemple le object2 et class2 sont respectivement le Fil objet de la classe TwoWire.

J'ai la nécessité d'appeler la bibliothèque de fildans une fonction de membre de mon Class1. Cette solution est une conséquence d'un cours précédent, où j'ai appris que je ne peux pas appeler une fonction de membre de Class1 dans une fonction non-membre, parce que l'instanciation de la fonction non-membre ne peut être que la classe n'est pas instancié comme un objet encore, et le compilateur n'a aucune idée sur la façon de le faire.

Mais appeler le fil . objet à l'intérieur d'une fonction de membre, je pensais que c'était possible. Mais penser mieux, en fait, lors du passage du pointeur de fonction membre classe1 au fil fonction, le compilateur ne peut pas savoir ce qu'il faut passer à fil, et donc ce qui suit est MAUVAIS:

void class1::functionA(void) 
{ 
    Wire.onRequest(class1::functionB); //wrong 
} 

où le onRequest accepte void (*)(void) fonctions.

donc essayer avec

void class1::functionA(void) 
{ 
    Wire.onRequest(&class1::functionB); //wrong 
} 

L'erreur est devenu:

error: no matching function for call to 'TwoWire::onRequest(void (class1::*)())' candidates are: void TwoWire::onRequest(void (*)())

Il y a une façon de faire ces choses fonctionnent? Si je dis statique et liste initialiseur, je suis sur la bonne voie avec les bons mots-clés?

Merci

+0

Had supprimer ma réponse. Je ne pense pas que ce soit clairement faisable. Vous devez passer 'this' de votre instance' class1' à 'onRequest', et vous ne pouvez pas le faire si vous acceptez' void (*)() '(aucun paramètre n'est autorisé). Une bibliothèque bien conçue définirait à la place 'onRequest' comme' onRequest (void (* callback) (void *), void * context) 'à la place, et vous passeriez' this' sous la forme 'context'. –

+0

La seule façon de faire cela est s'il n'y a qu'une seule instance 'class1' dans votre application entière - alors vous pouvez substituer cette instance inconditionnellement et appeler' functionB'. –

Répondre

1

&class1::functionB est un pointeur à fonction membre, pas un pointeur à la fonction. Son type est void (class1::*)(void), et non void (*)(void), comme prévu par la méthode onRequest. Cela signifie que pour appeler cette fonction pointer-to-member, il est également nécessaire d'avoir l'instance (class1*). Si le class1 est un singleton, la manière la plus simple de résoudre ce problème est probablement de faire functionB un membre statique ou simplement une fonction non membre (pas dans une classe). Si class1 ne peut pas être supposé singleton, alors la bibliothèque doit avoir un moyen de passer un pointeur de contexte (habituellement void*) le long du pointeur vers la fonction et ce contexte est un paramètre de la fonction de rappel. Vous devez passer this comme le contexte et un pointeur vers une fonction d'emballage, comme ce qui suit:

void wrapper_for_class1_functionB(void* context) 
{ 
    static_cast<class1*>(context)->functionB(); 
} 

void class1::functionA(void) 
{ 
    Wire.onRequest(&wrapper_for_class1_functionB, this); 
} 
+0

Le but n'est pas de le faire singleton, en plus les structures de données sont définies dans la classe. Cela signifie que je ne peux pas utiliser une fonction non-membre car elle contient le traitement des données des structures définies dans la classe. – thexeno

+0

J'ai alors essayé avec votre suggestion, semble très intéressant, mais cela nécessite, encore une fois, de modifier la bibliothèque de fil pour prendre un autre argument. En fait, l'erreur que j'ai obtenue est une fonction non correspondante. Est-ce que je manque quelque chose? – thexeno

+0

Et de toute façon, aussi les fonctions dans le "functionB()" il y a d'autres fonctions membres qui doivent être appelées en dehors du .cpp, donc dans le fichier principal, quand l'objet est créé. – thexeno