Frage

Warum, zum Beispiel, gibt es keine Sprachunterstützung eine VTable zu untersuchen? Warum kann ich nicht ein Mitglied Funktion durch einen neuen ersetzen? Ich habe ein Bauchgefühl, dass es Möglichkeiten gibt, solche Eigenschaften für einen guten Zweck zu setzen.

Gibt es noch andere Sprachen gibt, die mir erlauben, solche Dinge zu tun?

War es hilfreich?

Lösung

Der Hauptgrund ist, dass die Beibehaltung VTable als Implementierungsdetail ermöglicht jede konkrete Umsetzung zu optimieren, wie es für richtig hält; Dies bedeutet, dass es kann z.B. trimmen oder sogar eliminieren VTable völlig, wenn es, dass es keine virtuellen Anrufe für eine bestimmte Methode (oder alle Methoden) unter Beweis stellen kann. Oder es kann einen VTable Versand mit einem if-else-Typ überprüfen, ob beispielsweise ersetzen es sieht, dass es nur wenige Alternativen (dies von Vorteil sein kann, weil Verzweigungsvorhersage in diesem Fall funktionieren wird, aber nicht mit vtables, und auch, weil if-else-Zweige können dann inlined werden). Es kann Methoden in VTable so neu anordnen, dass am häufigsten genannt diejenigen früher kommen, oder so, dass diejenigen, die häufig eine nach der anderen füllen benachbarte Schlitze in VTable Vorteil des Caching nehmen genannt werden. Und so weiter und so fort. Natürlich sind alle diese Implementierungen würden auch VTable Layout völlig unvorhersehbar und damit unbrauchbar machen, wenn es (durch die Sprachspezifikation) die Umsetzung ausgesetzt werden sollten.

Wie gut, vtables sind nicht so einfach, wie sie klingen zu sein. Zum Beispiel müssen Compiler oft Thunks erzeugen this Zeiger für Dinge solche virtuelle Vererbung oder Mehrfachvererbung in Kombination mit kovarianten Rückgabetypen fixieren-up. Das ist wieder etwas, das nicht einen „bester Weg“ hat, es zu tun (weshalb verschiedene Compiler es anders machen) und zu standardisiert sie effektiv auf eine bestimmte Art und Weise Einschwingzeit erfordern würden.

, die sagt: „VTable switching“ ist eine potentiell nützliche Technik, wenn sie als ein übergeordnetes Konstrukt ausgesetzt (so dass Optimierungen sind noch möglich). Ein Beispiel finden Sie Unreal, die man mehrere Staaten für eine Klasse (ein Standard, andere definieren können genannt), und einige Methoden in benannten Staaten außer Kraft setzen. Abgeleitete Klassen können weitere Methoden in bestehenden Staaten außer Kraft setzen oder ihre eigenen Zustände hinzufügen und in ihnen außer Kraft setzen. Darüber hinaus können andere Zustände Zustände erstrecken (so dass, wenn eine Methode nicht für einen bestimmten Zustand außer Kraft gesetzt wird, es zurück zu dem „Eltern“ Zustand fällt, und so weiter, bis die Kette, die den Zustand Standard erreicht). Für Schauspieler Modellierung (die im Wesentlichen Spiele) das alles macht sehr viel Sinn, weshalb Unreal hat. Und die offensichtliche effiziente Umsetzung Mechanismus für all dies ist VTable Schalt, wobei jeder Zustand einen separaten VTable haben.

Andere Tipps

Weil es eine Implementierung Detail des Compilers ist. Dass die Umsetzung kann sich ändern, und jeder Code, der darauf beruht wäre bestenfalls fragil.

C ++ ist eine Sprache, wo man nie ‚bezahlen‘, was Sie nicht verwenden. Diese Art von Laufzeitunterstützung würde diese Philosophie widersprechen.

Es gibt viele Sprachen (auf dem dynamischeren Ende des Spektrums), die das unterstützen.

Weil es muss nicht als VTable umgesetzt werden, obwohl dies in der Regel der Fall ist. Kurz gesagt, ist es nicht so etwas wie VTable in C ++!

Sie JavaScript, Python und Ruby können alle tun. In diesen Sprachen Klassen- und Instanzdefinitionen sind wandelbar zur Laufzeit. Abstractly, jedes Objekt und Typ ist ein Wörterbuch von Elementvariablen und Methoden, die überprüft und aktualisiert werden können.

Das in C ++ nicht möglich ist, weil es in der Lage erfordern würde generierte Binärcode neu zu schreiben, die einen erheblichen Leistungseinbußen führen kann.

vtables existieren nur unter bestimmten Umständen in einigen Compiler (das heißt, sie sind nicht in dem Standard, aber eine Implementierung Detail angegeben). Selbst wenn es sie gibt, kommen sie nur, wenn Sie virtuelle Funktionen haben und müssen den Indirektionsoperator Polymorphismus zu implementieren. Wenn dies nicht erforderlich ist, kann sie optimiert werden, auf den Anruf unter der Last der Indirektion zu speichern.

Leider (oder auf andere Weise, auf Ihren Ansichten zu diesem Thema je ;-), wurde C ++ nicht darauf ausgelegt, Affen Patchen zu unterstützen. In einigen Fällen (zum Beispiel COM) ist die V-Tabelle ein Teil der Implementierung und Sie könnten in der Lage sein, hinter den Kulissen stochern. Dies würde jedoch nie unterstützt oder tragbar sein.

Ich glaube, Sie Dinge wie die in dynamischen Sprachen wie Python tun können:

>>> class X():
...     def bar(self): print "bar"
...     
>>> x = X()
>>> x.bar()
bar
>>> def foo(x): print "foo"
... 
>>> X.bar = foo
>>> x.bar()
foo

Der Unterschied zu einer statischen Sprache wie C ++ ist, dass der Interpreter alle Namen zur Laufzeit sucht und entscheidet dann, was zu tun ist.

In C ++ gibt es wahrscheinlich andere Lösungen für den „ersetzen, um eine Elementfunktion mit einem anderen“ Problem, die einfachste davon Funktionszeiger verwenden könnte:

#include <iostream>

class X;
typedef void (*foo_func)(const X&);

void foo(const X&) { std::cout << "foo\n"; }
void bar(const X&) { std::cout << "bar\n"; }

class X
{
    foo_func f;
public:
    X(): f(foo) {}
    void foobar() { f(*this); }
    void switch_function(foo_func new_foo) { f = new_foo; }
};

int main()
{
    X x;
    x.foobar();
    x.switch_function(bar);
    x.foobar();
}

(foo und bar nicht das X verwenden & Argument, in diesem Beispiel, ähnlich dem Python Beispiel)

Ich arbeite an einem statisch kompilierte Sprache, die die V-Tabelle macht, und glauben Sie mir, es ist ein bisschen von Haare zu belichten.

  • Alles, was Sie in C ++ tun, Sie in geraden C mit einem wenig Fett Ellenbogen tun.
  • Jede bescheiden und vernünftig C-Programm sollte in C ++ kompiliert.

Vielleicht, was Sie wollen, ist Ihr eigenes vtables zu implementieren, ohne C ++ 's Einbau-Anlage zu verwenden. Sie werden viel Spaß haben mit Zeiger-to-Mitglied-Funktionen (PTMF ist)!

Sie werden Schwierigkeiten haben, eine kompilierte Sprache mit Vtable Innerlichkeit zu finden, weil es wenig Nachfrage und es ist nicht einfach zu implementieren. Für interpretierte Sprachen, aber ist die Situation umgekehrt.

  

Gibt es andere Sprachen aus   es, die mir erlauben, so zu tun,   Dinge?

Objective-C (und Objective-C ++ als auch) ermöglichen die Laufzeit Ersatz von bereits kompilierten Methoden. Es ist entweder die beste Kombination von statischen und dynamischen Techniken oder das Schlimmste, je nachdem, wen man fragt.

Wie andere haben darauf hingewiesen, es gibt kein Konzept von „V-Tabelle“ in der C ++ Standard, wie es ist nur eine nahezu universelle Implementierungstechnik, ähnlich wie Namen Mangeln.

Wenn Sie suchen in der Lage, Funktionen on the fly in einer kompilierten Sprache neu zu definieren, könnten Sie in Common Lisp interessieren. Es hat andere sein, aber die einzigen anderen Sprachen, die ich von entweder statische Vererbung und Funktionen denken kann, oder werden zu einem groß Kosten in der Leistung interpretiert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top