Warum kann ich keine Vererbung verwenden, um eine Schnittstelle in C ++ zu implementieren? [Duplikat]

8

Unter Berücksichtigung dieser Objekte:

%Vor%

Ich frage mich, warum - compiler-weise - das folgende Objekt als abstrakt betrachtet wird:

%Vor%

Der Compiler lässt mich das nicht tun:

%Vor%

Visual Studio 2010 sagt:

  

'C': kann die abstrakte Klasse aufgrund folgender Elemente nicht instanziieren: 'void A :: foo (void)': ist abstrakt: siehe Deklaration von 'A :: foo'

g ++ 4.6.3 sagt:

  

kann kein Objekt vom abstrakten Typ 'C' zuordnen, da die folgenden virtuellen Funktionen in 'C' rein sind: virtual void A :: foo ()

Ich denke, das ist in C # erlaubt, aber ich kenne die beteiligten Mechanismen nicht - ich bin nur neugierig.

    
mister why 10.05.2012, 12:16
quelle

4 Antworten

4

struct B implementiert eine Funktion, die zufällig foo heißt und keine Argumente annimmt. Diese Funktion hat offensichtlich absolut keine Beziehung zu A::foo . Wenn also struct C sowohl von A als auch von B stammt, hat es geerbt:

  • die Verantwortung, eine Implementierung für A::foo bereitzustellen
  • eine Methode B::foo , die denselben Namen und dieselbe Signatur wie A::foo hat, aber in keiner Weise damit in Beziehung steht

Ich denke, das Problem ist offensichtlich. Sie versuchen, A als Äquivalent zu einem C # interface zu verwenden, aber es gibt keine Möglichkeit, dieses Konzept in C ++ auszudrücken.

Jetzt hilft auch die using Direktive nicht, da sie B::foo nur in den Bereich von C bringt, was bedeutet, dass sie dem Compiler sagt, dass sie B::foo als einen Kandidaten für die Auflösung des Namens betrachten sollte foo , wenn letzterer in der Klasse C angetroffen wird. Leider hat das auch nichts mit der Verantwortung zu tun, rein virtuelle Methoden zu implementieren.

    
Jon 10.05.2012, 12:24
quelle
7

Leider tut das nicht ganz, was Sie wollen.

Eine using -Direktive bringt nur einige Namen in den Bereich, in dem sie verwendet wird. virtual Methoden müssen überschrieben werden, und nur Namen werden nicht als überschreibend betrachtet.

Die Wahrheit ist, dass C ++ delegation nicht direkt unterstützt. Es gibt nur diesen kleinen Unterschied, Namen explizit in den Geltungsbereich zu bringen.

    
Matthieu M. 10.05.2012 12:25
quelle
2

Um dieses Problem zu lösen, müssen Sie Ihr eigenes foo() in C implementieren und explizit die B-Funktion aufrufen, um A :: foo innerhalb von C:

an B :: foo weiterzuleiten %Vor%

Es macht auf einer bestimmten Ebene Sinn - es gibt keine inhärente Beziehung zwischen A :: foo () und B :: foo () - Sie müssen innerhalb von C explizit eine festlegen.

    
Drew Hall 10.05.2012 12:30
quelle
1
  

Ich denke, das ist in C # erlaubt

C ++ ist nicht C #.

virtual void foo() und void foo() sind zwei verschiedene Methoden.

Wenn Sie von A und B ableiten, erhalten Sie Zugriff auf zwei Methoden: virtual A::foo und nicht-virtuelles B::foo . Und virtual A::foo ist abstrakt. Daher der Compilerfehler.

    
SigTerm 10.05.2012 12:34
quelle

Tags und Links