2013-02-25 15 views
7

Ich lerne jetzt C++, die OO Seite, und ich habe die ganze Zeit:C++ Unterschied zwischen virtuell = 0; und leere Funktion

class SomeClass{ 
    virtual void aMethod()=0; 
} 

class AnotherClass{ 
    void anotherMethod(){/*Empty*/} 
} 

class SomeClassSon : public SomeClass{ 
    void aMethod(){/*Also Empty*/} 
} 

Mein Zweifel ist: Was ist der Unterschied zwischen den drei Methoden. Das virtuelle ist gleich Null, das leere und das virtuelle, da es vererbt ist, leer.

Warum kann ich nicht machen nur die SomeClassSon Methode wie der Vater (virtual void gleich Null?)

+0

'SomeClass s; s.aMethod() 'ist kein gültiger Aufruf. – andre

+3

Der Unterschied ist, mit der '= 0' in der Basisklasse muss jede abgeleitete Klasse * die Methode implementieren. –

+2

@DavidSchwartz - muss die Funktion * implementieren, wenn die Klasse instanziiert * wird. Wenn die Funktion nicht implementiert ist, ist die Klasse abstrakt. –

Antwort

10

Für Ihre

class SomeClass{ 
    virtual void aMethod()=0; 
} 

Gegenwart eines rein virtuelle Methode macht Ihre Klasse abstrakte. Sobald Sie eine solche reine virtuelle Methode, =0, in Ihrer Klasse haben, können Sie die Klasse nicht instanziieren. Darüber hinaus muss jede abgeleitete Klasse das reine virtuelle aMethod() implementieren, oder es wird auch eine abstrakte Klasse.

In Ihrer abgeleiteten Klasse überschreiben Sie die reine virtuelle Methode von oben, und dies macht die abgeleitete Klasse nicht abstrakt. Sie können diese abgeleitete Klasse instanziieren.

Aber in der abgeleiteten Klasse ist der Körper der Methode leer, oder? Deshalb macht Ihre Frage Sinn: Warum sollten Sie die Klasse nicht auch rein virtuell machen? Nun, deine Klasse kann andere Methoden beinhalten. Wenn dies der Fall ist, kann SomeClass nicht instanziiert werden (es gibt eine reine virtuelle Methode), wohingegen die untergeordnete Klasse SomeClassSon sein kann.

Gleiches gilt für Ihre AnotherClass, die im Gegensatz zu SomeClass instanziiert werden kann.

6

Der Unterschied besteht darin, dass virtual void aMethod() = 0 ein pure virtual function ist, was bedeutet, dass:

  1. SomeClass eine wird abstrakte Basisklasse, bedeutet, dass es nicht instanziiert werden kann.
  2. Jede Klasse, die von SomeClass erbt muss aMethod implementieren, oder es wird zu einer abstrakten Basisklasse, den

Hinweis kann nicht instanziert, dass jede Klasse mit einer oder mehrer reinen virtuellen Funktionen automatisch eine abstrakte Basisklasse ist.

+1

Vielleicht meintest du das Richtige, aber sagst es falsch: Klassen, die von 'SomeClass' abgeleitet sind, sind * nicht * gezwungen, die Funktion zu implementieren, aber wenn sie das nicht tun, sind sie auch abstrakt. –

1

Ein reines virtual macht die Klasse abstrakt. Eine leere nicht-virtuelle Methode tut nichts - es führt nur zu einem Linker-Fehler, wenn Sie versuchen, es aufzurufen. Im Gegensatz dazu können Sie nicht versuchen, einen reinen virtual aufzurufen (es sei denn, Sie versuchen, es von einem Konstruktor aufzurufen, der sowieso schlecht ist), weil der Compiler Sie das Objekt nicht erstellen lässt.

Es gibt auch einen logischen Unterschied - die mit virtual markierte Methode wird virtuell durch die Vererbungskette sein - die anderen sind nur normale Methoden.

1

Eine reine virtuelle Funktion (Ihr erstes Beispiel mit der =0) bedeutet, dass die Funktion in einer abgeleiteten Klasse für ein Objekt dieser Klasse instanziiert werden muss, um instanziiert zu werden.

Die zweite ist im Grunde nur eine Member-Funktion, die nichts tut. Da die Funktion einen anderen Namen hat und die Klasse nicht mit SomeClass verknüpft ist, beeinflussen sich die beiden nicht gegenseitig.

Die dritte überschreibt die reine virtuelle Funktion, daher ist es möglich, SomeClassSon instanziieren, aber in der abgeleiteten Klasse tut die überschriebene Funktion nichts.

2

Die Deklaration aMethod() = 0 teilt dem Compiler mit, dass diese Methode in Unterklassen bereitgestellt werden muss. Jede Unterklasse, die die Methode nicht implementiert, kann nicht instanziiert werden. Dadurch können Sie sicherstellen, dass für alle Objekte der Basisklasse die Methode implementiert ist.

3

Das "equals 0", auf das Sie sich beziehen, heißt "pure virtual". Es ist eine Funktion, die das Kind, das instantiiert werden will, implementieren muss, anstatt Basisfunktionalität bereitzustellen, was bedeutet, dass die Elternklasse Funktionen definieren wird, die existieren müssen, aber dass die Eltern nicht wissen, wie das Kind es tun wird. Beachten Sie, dass die Klasse dadurch abstrakt wird, dass sie nicht instanziiert werden kann. Zum Beispiel möchte ich eine "Säugetier" -Klasse definieren, von der ich erben kann, und ich möchte, dass ihre Kinder auf eine bestimmte Art und Weise handeln - aber ich kann nicht einfach ein "Säugetier" machen. Stattdessen würde ich eine "Giraffe" -Klasse erstellen und sicherstellen, dass sie sich so verhält, wie sie sollte.

Es wird auch an dieser SO Frage erläutert.

Die "Empty" -Funktion, auf die Sie sich beziehen, ist stattdessen eine Funktion, wo die Funktion definiert ist und aufgerufen werden kann - tut aber nichts.

Verwandte Themen