webentwicklung-frage-antwort-db.com.de

Warum wird eine rein virtuelle Funktion mit 0 initialisiert?

Wir deklarieren eine rein virtuelle Funktion immer als:

virtual void fun () = 0 ;

Das heißt, es wird immer 0 zugewiesen.

Was ich verstehe ist, dass dies den vtable-Eintrag für diese Funktion auf NULL initialisieren soll und jeder andere Wert hier zu einem Kompilierungszeitfehler führt. Ist dieses Verständnis richtig oder nicht?

145
mukeshkumar

Der Grund =0 wird verwendet, wenn Bjarne Stroustrup nicht glaubte, dass er ein anderes Schlüsselwort erhalten könnte, wie "pure", das zum Zeitpunkt der Implementierung des Features an der C++ - Community vorbeigegangen war. Dies ist in seinem Buch The Design & Evolution of C++ , Abschnitt 13.2.3 beschrieben:

Die neugierige = 0-Syntax wurde gewählt ... weil ich zu der Zeit keine Chance sah, ein neues Schlüsselwort zu akzeptieren.

Er erklärt auch ausdrücklich, dass dies nicht erforderlich ist, um den Eintrag vtable auf NULL zu setzen, und dass dies nicht der beste Weg ist, um rein virtuelle Funktionen zu implementieren.

159
anon

Wie bei den meisten "Warum" -Fragen zum Design von C++ ist der erste Ort, an dem Sie nachsehen müssen, Das Design und die Entwicklung von C++ von Bjarne Stroustrup1:

Der neugierige =0 Die Syntax wurde der offensichtlichen Alternative der Einführung eines neuen Schlüsselworts pure oder abstract vorgezogen, da ich zu diesem Zeitpunkt keine Chance sah, ein neues Schlüsselwort zu akzeptieren. Hätte ich pure vorgeschlagen, hätte Release 2.0 ohne abstrakte Klassen ausgeliefert. Da ich zwischen einer besseren Syntax und abstrakten Klassen wählen konnte, entschied ich mich für abstrakte Klassen. Anstatt eine Verzögerung zu riskieren und bestimmte Kämpfe um pure zu führen, verwendete ich die traditionelle C- und C++ - Konvention, 0 zu verwenden, um "nicht da" darzustellen. Das =0 Syntax passt zu meiner Ansicht, dass ein Funktionskörper der Initialisierer für eine Funktion ist, auch mit der (vereinfachten, aber normalerweise angemessenen) Ansicht der Menge von virtuellen Funktionen, die als Vektor von Funktionszeigern implementiert werden. [...]

1§13.2.3 Syntax

76
Jerry Coffin

Abschnitt 9.2 des C++ - Standards enthält die Syntax für Klassenmitglieder. Es beinhaltet diese Produktion:

pure-specifier:
    = 0

Der Wert hat nichts Besonderes. "= 0" ist nur die Syntax für "diese Funktion ist rein virtuell". Es hat nichts mit Initialisierung oder Nullzeigern oder dem numerischen Wert Null zu tun, obwohl die Ähnlichkeit mit diesen Dingen einen mnemonischen Wert haben kann.

29

Ich bin mir nicht sicher, ob dahinter eine Bedeutung steckt. Es ist nur die Syntax der Sprache.

19
cquillen

C++ hat immer darauf verzichtet, neue Schlüsselwörter einzuführen, da neue reservierte Wörter alte Programme beschädigen, die diese Wörter als Bezeichner verwenden. Es wird oft als eine der Stärken der Sprache angesehen, alten Code so weit wie möglich zu respektieren.

Die Syntax = 0 Könnte tatsächlich gewählt worden sein, da sie dem Setzen eines vtable-Eintrags auf 0 Ähnelt, dies ist jedoch rein symbolisch. (Die meisten Compiler weisen solche vtable-Einträge einem Stub zu, der einen Fehler ausgibt, bevor das Programm abgebrochen wird.) Die Syntax wurde hauptsächlich gewählt, weil sie zuvor für nichts verwendet wurde und die Einführung eines neuen Schlüsselworts erspart hat.

15
sbi

C++ muss eine Möglichkeit haben, eine reine virtuelle Funktion von einer Deklaration einer normalen virtuellen Funktion zu unterscheiden. Sie entschieden sich für die = 0 Syntax. Sie hätten es einfach tun können, indem sie ein reines Schlüsselwort hinzugefügt hätten. Aber C++ ist ziemlich abgeneigt, neue Schlüsselwörter hinzuzufügen, und bevorzugt andere Mechanismen, um Funktionen einzuführen.

11
JaredPar

In diesem Fall wird nichts "initialisiert" oder "zugeordnet". = 0 in nur einem syntaktischen Konstrukt bestehend aus = und 0 Token, die absolut keine Beziehung zu Initialisierung oder Zuweisung haben.

Es hat keine Beziehung zu irgendeinem tatsächlichen Wert in "vtable". Die C++ - Sprache hat keine Ahnung von "vtable" oder dergleichen. Verschiedene "vtables" sind nichts weiter als Details spezifischer Implementierungen.

7
AnT

Ich erinnere mich, dass ich gelesen habe, dass die Rechtfertigung für die lustige Syntax darin bestand, dass es (in Bezug auf die Akzeptanz von Standards) einfacher war, als ein anderes Schlüsselwort einzuführen, das dasselbe tun würde.

Ich glaube, dass dies in Das Design und die Entwicklung von C++ von Bjarne Stroustrup erwähnt wurde.

3
luke

Ich würde annehmen, dass dies nur ein Teil der C++ Grammatik ist. Ich glaube nicht, dass es irgendwelche Einschränkungen gibt, wie die Compiler dies tatsächlich für ein bestimmtes Binärformat implementieren. Ihre Vermutung war wahrscheinlich richtig für die frühen C++ - Compiler.

2
rui

Das = 0deklariert eine rein virtuelle Funktion.

Was verstanden wird ist, dass dies dazu dient, den vtable-Eintrag für diese Funktion auf NULL zu initialisieren und jeder andere Wert hier zu einem Kompilierungszeitfehler führt

Ich glaube nicht, dass das stimmt. Es ist nur eine spezielle Syntax. Die vtable ist implementierungsdefiniert. Niemand sagt, dass ein Vtable-Eintrag für ein reines Mitglied beim Erstellen tatsächlich auf Null gesetzt werden muss (obwohl die meisten Compiler mit Vtables ähnlich umgehen).

2

Sie können den Eintrag vtable auch so initialisieren, dass er auf eine tatsächliche Funktion verweist. "

 virtual void fun()
 {
     //dostuff()
 }

Scheint intuitiv zu sein, dass der Eintrag vtable entweder so definiert werden kann, dass er nirgends (0) oder auf eine Funktion zeigt. Wenn Sie einen eigenen Wert dafür angeben, zeigt dieser wahrscheinlich auf Müll anstatt auf eine Funktion. Aber deshalb ist "= 0" erlaubt und "= 1" nicht. Ich vermute, Neil Butterworth hat recht, warum "= 0" überhaupt verwendet wird

1
Brian