Methodenzeiger

Ein Methodenzeiger wird bei objektorientierter Programmierung verwendet, um auf eine Methode einer Klasse oder einer Objektinstanz zu verweisen. Er ähnelt einem Funktionszeiger (einem Zeiger auf eine Funktion). In manchen Programmiersprachen ist es üblich, einen Methodenzeiger als Methode oder Referenz auf eine Methode zu bezeichnen. Es wird zwischen gebundenen und ungebundenen Methodenzeigern unterschieden, je nachdem wann der self- oder this-Parameter bestimmt wird.

Gebundene Methodenzeiger

Bei gebundenen Methoden (bound method in Python) enthält der Methodenzeiger einen Zeiger auf eine Methode und einen Zeiger auf eine Objektinstanz. Solche Methodenzeiger lassen sich als Rückruffunktion (callback function) nutzen, um Aktionen bei Ereignissen (engl.: Events) auszulösen.

Ungebundene Methodenzeiger

Bei ungebundenen (auch: freien) Methoden (unbound method in Python, Method in Java) enthält der Methodenzeiger einen Verweis auf eine Methode, aber keinen Verweis auf eine Objektinstanz. Einem ungebundenen Methodenzeiger muss beim Aufruf eine passende Objektinstanz übergeben werden.

In C++ existieren ebenfalls ungebundene Methodenzeiger. Diese zeigen auf eine Methode einer Klasse und werden beim Aufruf an ein Objekt gebunden. Hierfür existieren die Operatoren .* und ->*. Intern ist ein Methodenzeiger eine Nummer, welche einen Eintrag in der Methodentabelle der Klasse referenziert.

Auch Objective-C bietet ungebundene Methodenzeiger des Typs IMP. Wegen ihrer fehlenden Objektorientierung werden sie allerdings nur selten zur Verbesserung des Laufzeitverhaltens eingesetzt. Ansonsten wird das überlegene Konzept der Selektoren verwendet.

Beispiel in C++

#include <iostream>

class Auto {
public:
    // 4 "member functions" = "Methoden"
    void starten() {
        std::cout << "Starten..." << std::endl;
    }

    void beschleunigen(double beschleunigung);
    void bremsen(double verzoegerung);
    void ausschalten();
};

int main() {
    Auto a;

    // erzeuge method_ptr und initialisiere ihn mit Auto::starten
    void (Auto::*method_ptr)() = &Auto::starten;

    // rufe Methode, auf die method_ptr zeigt. in dem Falle: a.starten()
    (a.*method_ptr)();

    // FEHLER: Falscher Methodentyp, da Auto::beschleunigen einen Parameter
    // erwartet
    method_ptr = &Auto::beschleunigen;

    return 0;
}

Verwandte Konzepte

Delegates

In .NET-Sprachen wie C#, VB.NET oder D werden Delegate-Variablen für die Erstellung typsicherer Methodenzeiger verwendet. Zusätzlich unterstützen .NET-Delegates weitere Operationen.

Delegates in spät bindenden Sprachen

In spät bindenden Sprachen wie Objective-C ist zwischen der Nachricht („Methodenaufruf“) und der Methode zu unterscheiden. Der Compiler übersetzt eine Methode und deren Aufruf nicht in einen Index für eine vtab. Vielmehr bleibt die Nachricht unverändert bestehen. Die Liste der Methoden eines Objektes ist ein assoziatives Array, enthält also einen Verweis von Nachrichtenname auf Methode. Daher ist es möglich, erst zur Laufzeit anhand der Nachrichten zu entscheiden, welche Methode ausgeführt werden soll. Als Folge davon ist es nicht notwendig, die Klasse des Empfängers zu kennen oder dass die Methode bereits in einer bekannten Superklasse wenigstens abstrakt definiert ist.

// Instanz beliebiger (unbekannter) Klasse
id myDelegate;
// Nachrichtenname
SEL messageSelector = @selector(sender:doSomethingWithObject:);

if ([myDelegate respondsToSelector:messageSelector]) {
    [myDelegate sender:self doSomethingWithObject:anObject];
}

Es ist zu beachten, dass durch die Verwendung von id jede Instanz jeder beliebigen Klasse als Empfänger angenommen werden kann. Da Delegates nicht alle Methoden implementieren müssen, wird zur Laufzeit abgefragt, ob eine entsprechende Implementierung vorliegt. Delegating ist also ein Angebot, keine Pflicht. Es dient der Vermeidung von Ableitungen (White-Boxing) und Herstellung einer definierten API zur Funktionsspezialisierung. Implementierungsseitig lässt sich das Vorhandensein von Methodenimplementierung vortäuschen und auf diese Weise eine Nachricht weiterleiten (Forward-Invocation, Proxy).

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.