Sagen wir, wir haben das:
%Vor% Der Compiler wirft keinen Fehler, ich denke es ist, weil B auch eine abstrakte Klasse ist und daher foo
nicht von A implementieren muss.
Aber was bedeutet ein solches Konstrukt?
1) Verdeckt foo
von B foo
von A?
2) Die erste Klasse, die von B erbt und keine abstrakte Klasse ist, muss zwei Implementierungen bereitstellen:
%Vor% Der Compiler beschwert sich nur, wenn die Implementierung von B::foo()
fehlt, aber nicht über fehlende A::foo()
.
Alles in allem: Ist das eine Möglichkeit, rein virtuelle Methoden zu verstecken?
Wenn Sie zuerst erklären:
%Vor% Sie deklarieren die Methode foo
public, virtual und pure. Wenn eine Klasse mindestens eine reine Methode enthält, heißt sie abstract . Was heißt das? Dies bedeutet, dass die Klasse nicht instanziiert werden kann, da sie die reinen Methodenimplementierungen benötigt.
Sie können natürlich von einer abstrakten Klasse erben (ich würde sagen, dass Sie gezwungen sind, das zu tun, sonst was wäre die Notwendigkeit einer abstrakten Klasse, die Sie nicht benutzen, außer dass Sie eine Schnittstelle zur Verfügung stellen?) und Sie können auch von einer abstrakten Klasse erben und einige oder alle der reinen Methoden der Elternklasse nicht implementieren; In diesem Fall ist die Kindklasse ebenfalls abstrakt, was bei Ihrer Klasse B der Fall ist:
%Vor% In B könnten Sie die Deklaration virtual void foo() = 0;
einfach weglassen, weil die Definition bereits von der Basisklasse geerbt wurde. In diesem Fall ist Klasse B eine abstrakte Klasse und kann daher nicht wie A instanziiert werden.
Um Ihre Fragen direkter zu beantworten:
Setzt
foo
von Bfoo
von A aus?
Nein, tut es nicht. Beide deklarieren eine reine Methode (was in der Tat die gleiche Methode ist), daher gibt es nichts wirklich zu verstecken .
Die erste Klasse, die von B erbt und keine abstrakte Klasse ist, muss zwei Implementierungen wie die bereitgestellte bereitstellen?
Nein, natürlich nicht. Wie oben erwähnt, sind sie die gleiche Methode. Wenn also Klasse C eine Implementierung für foo
bereitstellen muss, sollte sie einfach foo
implementieren:
0) Der Compiler löst keinen Fehler aus ...
Es wird ein Fehler ausgegeben, wenn Sie versuchen, ein Objekt von A
oder B
zu instanziieren, was abstrakt ist. Nicht, wenn Sie sie erben und deklarieren.
1) Versteckt foo von B foo von A?
Nein. Es überschneidet A::foo
verbirgt es nicht.
2) Die erste Klasse, die von B erbt und keine abstrakte Klasse ist, muss es zwei Implementierungen bereitstellen ...
Nein. Überschreibe einfach foo
und mache eine Implementierung dafür.
%Vor%
Ich habe Ihren Code mit gcc 4.5.3 kompiliert und folgende Fehlermeldungen ausgegeben:
%Vor% In Ihrem Beispiel sind beide Klassen A
und B
abstrakte Klassen, da foo rein virtuell ist. Sie definieren nur, dass die abgeleitete Klasse von B das Verhalten von foo
implementieren soll, da kein Standardverhalten zu verwenden ist (wenn die abgeleitete Klasse nicht mehr abstrakt ist).
Question 1:Does foo from B hide foo from A?
Da foo
in B
und A
genau denselben Namen hat, ist die gleiche Signatur und foo in der Basisklasse virtuell, also versteckt sie sich nicht, sie überschreibt. FYI: Die Funktion overrides
einer Basisklassenfunktion einer abgeleiteten Klasse, wenn die Signatur dieselbe ist und in der Basisklasse als virtuell deklariert ist. Wenn Sie es anrufen
durch einen Zeiger oder eine Referenz auf die Basisklasse, die Funktion in der
abgeleitete Klasse wird aufgerufen. Es "überschreibt" das in der Basisklasse.
Hiding
kommt nur ins Spiel, wenn Sie eine nicht-virtuelle Funktion über a aufrufen
Zeiger oder Verweis oder direkt mit einem Objekt der abgeleiteten Klasse. EIN
Die Funktion der abgeleiteten Klasse blendet alle Basisklassenfunktionen mit demselben Namen aus.
Question 2: The first class which inherits from B and is not an abstract class, does it have to provide two implementations
Nein. Sie können Folgendes tun:
%Vor%Tags und Links c++ inheritance virtual