Zeigen eine Variable auf eine Member-Funktion in C ++

Es ist überraschend zu erfahren, dass die meisten C ++ Programmierer haben keine Ahnung, dass ein Zeiger genannt Dies besteht. Damit Dies ist ein großes Geheimnis! Schwelgen Sie in it! Was ist das Geheimnis? Das Geheimnis ist, dass Sie die Adresse eines Mitgliedsfunktion des Objekts übernehmen kann, so dass Sie die direkt Instanzdatenmemberfunktion zugreifen können. Ooh-wee!

Jetzt denken Sie daran, dass jede Instanz einer Klasse seine eigene Kopie der Mitgliedsvariablen wird, es sei denn, die Variablen statisch sind. Aber Funktionen werden in der gesamten Klasse geteilt. Ja, können Sie statische Funktionen von nicht-statische Funktionen unterscheiden.

Aber das bezieht sich nur auf, welche Arten von Variablen sie zugreifen: Statische Funktionen nur statische Member-Variablen zugreifen können, und Sie müssen nicht mit einer Instanz, um sie zu verweisen. Nicht-statischen (dh, normale, regelmäßige) Member-Funktionen arbeiten mit einer bestimmten Instanz. Doch im Inneren des Speichers, wirklich nur eine Kopie der Funktion vorhanden ist.

Wie weiß die Member-Funktion, welche Instanz mit zu arbeiten? Ein geheimer Parameter wird in die Member-Funktion übergeben: die Dies Zeiger. Angenommen, Sie haben eine Klasse namens Gobstopper das hat eine Member-Funktion aufgerufen Kauen(). Als nächstes müssen Sie eine Instanz namens MyGum, und rufen Sie die Kauen() Funktion wie folgt:

MyGum.Chew () -

Wenn der Compiler Assembler-Code für diese erzeugt, es geht tatsächlich um einen Parameter in der Funktion - die Adresse der MyGum beispielsweise auch bekannt als thispointer. Daher nur eine Kauen() Funktion ist im Code, aber es nennen Sie eine bestimmte Instanz der Klasse verwenden.

Da nur eine Kopie der Kauen() Funktion ist im Speicher ist, wird seine Adresse zu nehmen. Aber das zu tun erfordert so eine Art von kryptischen aussehenden Code. Hier ist es, schnell und auf den Punkt. Angenommen, Ihre Klasse wie folgt aussieht:

Klasse Gobstopper {public: int WhichGobstopper-int Chew (string name) {cout lt; lt; WhichGobstopper lt; lt; Endl-cout lt; lt; Name lt; lt; Endl-return WhichGobstopper -}} -

Das Kauen() Funktion nimmt einen String und gibt eine ganze Zahl. Hier ist ein typedef für einen Zeiger auf die Kauen() Funktion:

typedef int (Gobstopper :: * GobMember) (string) -

Und hier ist eine Variable vom Typ GobMember:

GobMember func = Gobstopper :: Kau-

Wenn Sie genau hinsehen, um die typedef, es sieht eine regelmäßige Funktionszeiger ähnlich. Der einzige Unterschied besteht darin, dass der Klassenname und zwei Doppelpunkte das Sternchen vorangestellt. Other than that, ist es eine regelmäßige alte Funktionszeiger.

Aber während eine regelmäßige Funktionszeiger beschränkt sich auf die Funktionen eines bestimmten Satzes von Parametertypen zu zeigen und einen Rückgabetyp dieser Funktion Zeiger Aktien diese Beschränkungen hat aber eine weitere Einschränkung: Es können nur auf Member-Funktionen innerhalb der Klasse Gobstopper.

Um die Funktion im Zeiger gespeicherten Nummern anrufen, müssen Sie eine bestimmte Instanz zu haben. Beachten Sie, dass bei der Zuordnung von func in dem früheren Code gab es keine Instanz, sondern nur die Class-Name und Funktion, Gobstopper :: Chew. So kann die Funktion aufgerufen, um eine Instanz greifen, fügen func, und gehen!

Das FunctionPointer02 Beispiel gezeigt enthält ein vollständiges Beispiel mit der Klasse, die Member-Funktion Adresse und zwei separate Instanzen.

#einschließen #einschließen using namespace std-Klasse Gobstopper {public: int WhichGobstopper-int Chew (string name) {cout lt; lt; WhichGobstopper lt; lt; Endl-cout lt; lt; Name lt; lt; Endl-return WhichGobstopper -}} - int main () {typedef int (Gobstopper :: * GobMember) (string) -GobMember func = Gobstopper :: Chew-Gobstopper inst-inst.WhichGobstopper = 10-Gobstopper another-another.WhichGobstopper = 20- (inst * func.) ( "Greg W.") - (. Andere * func) ( "Jennifer W.") -return 0-}

Sie können sehen, in Main dass zuerst erstellen Sie den Typ für die Funktion, die Sie aufrufen GobMember, und erstellen Sie eine Variable, func, dieses Typs. Dann erstellen Sie zwei Instanzen der Gobstopper Klasse, und Sie geben ihnen jeweils eine andere WhichGobstopper Wert.

Schließlich rufen Sie die Member-Funktion, zunächst für die erste Instanz und dann für die zweite Instanz. Nur um zu zeigen, dass Sie die Adressen von Funktionen mit Parametern erfolgen kann, übergeben Sie in einem String mit einigen Namen.

Wenn Sie den Code ausführen, können Sie aus der Ausgabe zu sehen, dass es in der Tat für jede Instanz die korrekte Memberfunktion aufruft:

10Greg W.20Jennifer W.

Nun, wenn Sie sagen, # 147-die richtige Elementfunktion für jede Instanz, # 148-, was Sie wirklich meine ist, dass der Code die gleiche Elementfunktion jedes Mal, ruft aber eine andere Instanz verwenden. Wenn Sie in der objektorientierten Begriffen zu denken sind, sollten Sie jede Instanz als seine eigene Kopie des Mitgliedsfunktion. Daher ist es in Ordnung zu sagen, # 147-die richtige Memberfunktion für jede Instanz # 148.

Menü