2016-05-11 16 views
4

Angenommen, ich habe diese zwei Klassen:C++ späte Bindung auf Funktion überlastet

class Hello { 
    //members 
public: 
    virtual int doit() { 
     return 3; 
    } 

}; 

class Wow : public Hello { 
    //members 
public: 
    virtual int doit() { 
     return 2; 
    } 
}; 

int main(int argc, const char *argv[]) { 

    Hello *c = new Wow(); 

    return c->doit(); 
} 

Wie wir alle wissen, wird dieser Code durch eine späte Bindung in C behandelt werden ++, in LLVM IR von Clang wie folgt umgesetzt:

; ... 
    %7 = bitcast %class.Wow* %5 to %class.Hello* 
    store %class.Hello* %7, %class.Hello** %c, align 8 
    %8 = load %class.Hello*, %class.Hello** %c, align 8 
    %9 = bitcast %class.Hello* %8 to i32 (%class.Hello*)*** 
    %10 = load i32 (%class.Hello*)**, i32 (%class.Hello*)*** %9, align 8 
    %11 = getelementptr inbounds i32 (%class.Hello*)*, i32 (%class.Hello*)** %10, i64 0 
    %12 = load i32 (%class.Hello*)*, i32 (%class.Hello*)** %11, align 8 
    %13 = call i32 %12(%class.Hello* %8) 
; ... 

Meine Frage ist, was passiert, wenn ich schaffen will eine Funktion check zum Beispiel in einem anderen Namensraum wie folgt aufgerufen:

namespace somewhereelse { 
    void check(Hello *c) { 
    // Do something 
    } 
    void check(Wow *c) { 
    // Do something else 
    } 
} 

Kann eine Art späte Bindung auf verschiedene Funktionsüberlastungen angewendet werden?

+0

Ich bin ein bisschen verwirrt, diese Überlastungen in der Tat funktionieren und die richtige Version von 'check' wird je nach Art des an die Funktion übergebenen Zeigers aufgerufen. Was erwartest du darüber hinaus? – johnbakers

+0

Ich gebe nur einen Zeiger auf die Oberklasse, offensichtlich. Ich brauche die Laufzeit, um die richtige Überladung zu wählen, abhängig vom Zielobjekt. Dies ist die Definition für späte Bindung – NoImaginationGuy

+0

ich sehe, würde nicht eine einzige 'check' Funktion akzeptieren die Basisklasse Zeiger in der Lage sein,' dynamic_cast' zu verwenden, um Verhalten für den wahren zugrunde liegenden Typ anzupassen? Sie müssten einen neuen Zeiger erstellen, ihn umwandeln und das Ergebnis testen, um zu sehen, ob dynamic_cast die Besetzung bestätigt hat. mehr Arbeit, aber ich denke, das ist, was dynamic_cast für – johnbakers

Antwort

4

Nein, dynamischer Versand für Nichtmitgliedsfunktionen ist derzeit nicht Teil von C++.

Es ist theoretisch möglich, aber die Implementierungstechnik ist nicht so geradlinig wie für virtuelle Funktionen. Es gab mehrere Vorschläge, um C++ damit zu erweitern (Schlüsselwörter: Multimethoden und Mehrfachversand), aber bis jetzt haben sie noch nicht zu einer konkreten vorgeschlagenen und akzeptierten Sprachänderung geführt.

+0

nicht enthält. So viel Interessantes. Es sollte zu neueren C++ - Standards hinzugefügt werden. Ich werde es wahrscheinlich in meinem Lang sicher implementieren. Vielleicht ein "virtuelles" Attribut, um Parametern zu geben, oder so ähnlich – NoImaginationGuy

+0

Lesen Sie die Literatur dazu. Es ist wirklich ein nicht-triviales Problem. –

-1

Das sieht wie ein Job für Funktionszeiger aus.

void (*checkPtr)(Hello*); 
... 
void check(Hello *c) { 
    // Do something 
    } 
... 
checkPtr = ✓ 

Es ist nicht perfekt, aber eine gute Problemumgehung für die späte Bindung.

Verwandte Themen