2016-06-21 4 views
7

Ich las ein Beispiel über Polymorphismus, die wie unten aussieht, wo show() eine virtuelle Funktion ist:Warum nicht früh binden, wenn möglich?

int main() 
{ 
    Derived dv1; 
    Derived dv2; 
    Base* ptr; 

    ptr = &dv1; 
    ptr->show(); 

    ptr = &dv2; 
    ptr->show(); 
} 

Die Bücher sagen, dass in diesem Fall der Compiler late binding Technik verwendet wird. Ich verstehe den Unterschied zwischen der späten Bindung und der frühen Bindung. In diesem Beispiel können wir (und vielleicht auch der Compiler) sehen, welche Funktion aufgerufen werden sollte, da die Objekte, auf die ptr zeigt, nicht geändert werden. Also, warum nicht früh in diesem Fall binden, weil späte Bindung etwas Overhead verursachen wird?

+4

Woher wissen Sie, dass Ihr Compiler diesen Fall nicht wirklich erkennt und einige Optimierungen dafür durchführt? Haben Sie den generierten Assemblercode überprüft? Mit aktivierten Optimierungen? –

+0

Ich bin nicht mit Assembler-Code vertraut. Die Tatsache, dass die Bücher sagen, dass die späte Bindung in diesem Fall angewendet wird, verwirrt mich. – Rickie

+2

Clang scheint zumindest [a * bit * more] (https://godbolt.org/g/9pnkg9) zu tun, als nur die Aufrufe zu optimieren, um abgeleitet zu werden, zumindest für einfache Implementierungen von 'show'. – jaggedSpire

Antwort

8

In diesem Beispiel können wir (und vielleicht auch der Compiler) sehen, welche Funktion aufgerufen werden sollte, da sich die Objekte, auf die ptr zeigt, nicht ändern.

Korrekt.

Also, warum früh Bindung in diesem Fall, weil späte Bindung wird einige Overhead verursachen?

Die Funktion wird über einen Zeiger auf einen polymorphen Typ aufgerufen, sodass eine späte Bindung verwendet wird.

Späte Bindung bedeutet einfach, dass der Aufruf in die abgeleitete Überschreibung aufgelöst wird (bis auf den konkreten Typ des Objekts) - anstatt den Aufruf auf Base::show aufzulösen.

Sicher, dynamische Dispatch möglicherweise für späte Bindung im Allgemeinen erforderlich sein, aber die Implementierung darf die Regeln zu brechen, wenn das Programm noch so verhält, als ob es den Regeln gefolgt wäre. Dies ist bekannt als die as-if Regel. Und aufgrund der Beobachtung, die Sie auch vorgenommen haben, ändert das Ändern des Programms für die statische Verteilung das Verhalten nicht, sodass der Compiler die dynamische Disposition optimieren und vermeiden kann.

+1

Diese Technik heißt _devirtualization_. Sie können über GCC-Implementierung in [Reihe von Blog-Posts] lesen (http://hubicka.blogspot.ru/2014/01/devirtualization-in-c-part-1.html) –

Verwandte Themen