Heim > Backend-Entwicklung > C++ > Hauptteil

C++-Syntaxfehler: Member-Funktionszeiger kann nicht auf Nicht-Member-Funktion zeigen, wie gehe ich damit um?

王林
Freigeben: 2023-08-22 16:43:47
Original
1485 Leute haben es durchsucht

C++-Syntaxfehler: Member-Funktionszeiger kann nicht auf Nicht-Member-Funktion zeigen, wie gehe ich damit um?

In der C++-Programmierung ist ein Member-Funktionszeiger ein Zeiger auf eine Member-Funktion einer Klasse. Durch die Verwendung von Zeigern auf Mitgliedsfunktionen können Sie dynamisch auswählen, welche Mitgliedsfunktion zur Laufzeit aufgerufen werden soll. Dies ist eine sehr nützliche Technik. Manchmal stoßen wir jedoch auf ein Problem, nämlich dass Member-Funktionszeiger nicht auf Nicht-Member-Funktionen verweisen können.

Zunächst müssen Sie verstehen, warum Mitgliedsfunktionszeiger nicht auf Nicht-Mitgliedsfunktionen verweisen können. Dies liegt daran, dass sich die Typen von Nicht-Member-Funktionen von denen von Member-Funktionen unterscheiden. Member-Funktionen müssen diesen Zeiger implizit übergeben, um auf Member-Variablen und -Funktionen der Klasse zuzugreifen. Daher speichert der Mitgliedsfunktionszeiger die Adresse der Mitgliedsfunktion und des Klassenzeigers, während die Nichtmitgliedsfunktion diesen Zeiger nicht hat und nicht auf die Mitgliedsvariablen und -funktionen der Klasse zugreifen kann, sodass der Mitgliedsfunktionszeiger nicht auf a zeigen kann Nichtmitgliedsfunktion.

Mit einigen Tricks können wir dieses Problem lösen. Hier sind einige Lösungen:

  1. Verwenden Sie Funktoren oder Lambda-Ausdrücke

Ein Funktor ist eine Klasse, die einen Funktionsaufrufoperator implementiert. Wir können den Funktionsaufrufoperator überladen, sodass Objekte einer Klasse wie Funktionen aufgerufen werden können. Daher können wir einen Funktor verwenden, um die Funktion einer Mitgliedsfunktion zu implementieren, sodass der Zeiger der Mitgliedsfunktion auf das Funktorobjekt zeigen kann. Auch Lambda-Ausdrücke können die gleiche Funktionalität erreichen.

Das Folgende ist ein Beispiel für die Verwendung eines Funktors:

#include <iostream>

class MyClass {
public:
    void foo() {
        std::cout << "Hello from foo!";
    }
};

class FunctionObject {
public:
    void operator()() {
        obj.foo();
    }
    MyClass obj;
};

int main() {
    FunctionObject f;
    f();
    return 0;
}
Nach dem Login kopieren

Im obigen Code definieren wir eine FunctionObject-Klasse, die ein MyClass-Objekt und eine Operator()-Funktion enthält. Wenn das Funktorobjekt aufgerufen wird, wird es als Operator bezeichnet ()-Funktion und ruft dadurch die foo-Funktion von MyClass auf.

Wir können die Funktion foo aufrufen, indem wir die Adresse des FunctionObject-Objekts an den Zeiger der Mitgliedsfunktion übergeben. Zum Beispiel:

void (MyClass::*func_ptr)() = &MyClass::foo;
FunctionObject f;
MyClass* p = &(f.obj);
(p->*func_ptr)();
Nach dem Login kopieren

Im obigen Code definieren wir einen Mitgliedsfunktionszeiger func_ptr, der auf die foo-Funktion von MyClass zeigt. Dann haben wir ein FunctionObject-Objekt f erstellt und die Adresse seines obj-Mitglieds dem MyClass-Zeiger p zugewiesen. Schließlich rufen wir die Funktion foo mit dem Member-Zugriffsoperator (p->*) und dem Member-Funktionszeiger func_ptr auf.

  1. Verwenden Sie globale Funktionen und void*-Zeiger

Eine andere Lösung besteht darin, globale Funktionen und void*-Zeiger zu verwenden. Wir können eine globale Funktion definieren, die einen void-Zeiger als Parameter akzeptiert, ihn in einen Zeiger auf die Klasse umwandelt und die Mitgliedsfunktion aufruft. Dann können wir die Adresse dieser globalen Funktion dem Mitgliedsfunktionszeiger zuweisen, um die Mitgliedsfunktion der Klasse aufzurufen.

Das Folgende ist ein Beispiel für die Verwendung einer globalen Funktion und eines void*-Zeigers:

#include <iostream>

class MyClass {
public:
    void foo() {
        std::cout << "Hello from foo!";
    }
};

void invoke_function(void* obj_ptr, void (*func_ptr)()) {
    MyClass* p = static_cast<MyClass*>(obj_ptr);
    (p->*func_ptr)();
}

int main() {
    void (*func_ptr)() = &MyClass::foo;
    MyClass obj;
    invoke_function(&obj, func_ptr);
    return 0;
}
Nach dem Login kopieren
Im obigen Code definieren wir eine globale Funktion invoke_function, die einen void

-Zeiger und einen Funktionszeiger als Parameter akzeptiert. In der Funktion invoke_function konvertieren wir den void -Zeiger obj_ptr in den MyClass-Zeiger p und verwenden den Member-Zugriffsoperator (p->*) und den Funktionszeiger func_ptr, um die foo-Funktion aufzurufen. In der Hauptfunktion definieren wir einen Mitgliedsfunktionszeiger func_ptr, der auf die foo-Funktion von MyClass zeigt. Dann erstellen wir ein MyClass-Objekt obj und übergeben seine Adresse an die Funktion invoke_function und übergeben dann func_ptr an die Funktion invoke_function.

Zusammenfassung

Der Member-Funktionszeiger ist ein leistungsstarkes Tool, mit dem wir die Member-Funktion dynamisch auswählen können, die zur Laufzeit aufgerufen werden soll. Wenn wir jedoch Mitgliedsfunktionszeiger verwenden und auf Nichtmitgliedsfunktionen verweisen müssen, können wir Funktoren oder Lambda-Ausdrücke verwenden oder globale Funktionen und void*-Zeiger verwenden. Diese Techniken können uns helfen, das Problem zu lösen, dass Member-Funktionszeiger nicht auf Nicht-Member-Funktionen verweisen können.

Das obige ist der detaillierte Inhalt vonC++-Syntaxfehler: Member-Funktionszeiger kann nicht auf Nicht-Member-Funktion zeigen, wie gehe ich damit um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage