2016-10-16 5 views
-1

Ich bin ziemlich neu in C++, und wahrscheinlich hatte ich naive Probleme. Ich weiß, dass es andere smilare Fragen gibt, die mit (anscheinend mir) komplexeren Problemen verbunden sind als meine. Ich versuche, eine Firmware für Arduino zu machen, mit C++ und ich habe mich mit den Überladungsfehlern verletzt.C++ - Grundlagen: ungelöst überladene Funktion Typ

ich diesen Code haben definieren in einer CPP-Datei:

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

Class1 wird initialisiert, wie:

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

Und in der Zusammenstellung gibt

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

Übersetzen ins das praktische:

in meinem Code Ich bin mit der Draht Bibliothek innerhalb einer Elementfunktion des class1 für eine Arduino Bibliothek, wo im Beispiel der object2 und class2 ist jeweils der Draht Objekt der Klasse TwoWire.

Ich habe die Notwendigkeit die Draht Bibliothek innerhalb einer Elementfunktion meiner class1 zu nennen. Diese Lösung ist eine Konsequenz aus früheren Lektionen, in denen ich gelernt habe, dass ich eine Elementfunktion von class1 innerhalb einer Nichtmitgliedsfunktion nicht aufrufen kann, da die Instanziierung der Nichtmitgliedsfunktion nicht vorgenommen werden kann, da die Klasse nicht ist instanziiert als ein Objekt noch, und der Compiler hat keine Ahnung, wie dies zu tun ist.

Aber den Draht benennend. Objekt in einer Member-Funktion, dachte ich, das war möglich. Aber das Denken besser es eigentlich beim Passieren der class1 Mitglied Funktionszeiger auf die Draht Funktion kann der Compiler nicht wissen, was zu Drähten passiert, so dass die folgende ist FALSCH:

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

wo die onRequest akzeptieren void (*)(void) Funktionen.

So mit

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

Der Fehler versucht wurde:

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

es eine Möglichkeit, die Dinge arbeiten zu machen ist? Wenn ich statische und Initialisierungsliste sage, bin ich auf dem richtigen Weg mit den richtigen Schlüsselwörtern?

Dank

+0

Hatte meine Antwort zu löschen. Ich denke nicht, dass dies einfach machbar ist. Sie müssen 'this' Ihrer' class1' -Instanz an 'onRequest' übergeben, und Sie können das einfach nicht tun, wenn es' void (*)() 'akzeptiert (keine Parameter erlaubt). Eine gut entworfene Bibliothek würde statt dessen "onRequest" als onRequest (void (* callback) (void *), void * context) definieren und "this" als "context" übergeben. –

+0

Der einzige Weg dies zu tun ist, wenn es nur eine 'class1'-Instanz in Ihrer gesamten Anwendung gibt - dann können Sie diese Instanz bedingungslos ersetzen und 'functionB' darauf aufrufen. –

Antwort

1

&class1::functionB ist ein Zeiger-zu-Element-Funktion, kein Zeiger-to-Funktion. Sein Typ ist , nicht void (*)(void), wie von der onRequest Methode erwartet. Dies bedeutet, dass zum Aufrufen dieser Zeiger-zu-Stab-Funktion auch die Instanz benötigt wird (class1*).

Wenn der class1 ein Singleton ist, ist der einfachste Weg, dies zu lösen wahrscheinlich functionB ein statisches Mitglied oder einfach eine Nicht-Mitglied-Funktion (nicht innerhalb einer Klasse).

Wenn class1 nicht Singleton davon ausgegangen wird, dann muss die Bibliothek eine Möglichkeit hat, einen Kontextzeiger zu übergeben (in der Regel void*) entlang der Zeiger auf Funktion und dieser Zusammenhang ist ein Parameter der Callback-Funktion. Sie sollten als Rahmen und einen Zeiger auf eine Wrapper-Funktion übergeben this, wie folgt aus:

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

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

Ziel ist es nicht, Singleton zu machen, tatsächlich sind auch die Datenstrukturen in der Klasse definiert. Das bedeutet, dass ich keine Nichtmitgliedsfunktion verwenden kann, da sie die Datenbehandlung von Strukturen enthält, die in der Klasse definiert sind. – thexeno

+0

Ich habe dann mit Ihrem Vorschlag versucht, scheint sehr interessant, aber das wiederum erfordert, die Wire-Bibliothek zu ändern, um ein anderes Argument zu nehmen. In der Tat ist der Fehler, den ich bekam, eine nicht übereinstimmende Funktion. Fehle ich etwas? – thexeno

+0

Und trotzdem, auch die Funktionen in der "functionB()" gibt es andere Member-Funktionen, die außerhalb der .cpp aufgerufen werden müssen, also in der Hauptdatei, wenn das Objekt erstellt wird. – thexeno