Abstrakte Klasse ohne abstrakte Methoden

8

Ist es möglich, in C ++ eine abstrakte Klasse zu erstellen, ohne abstrakte Methoden zu deklarieren? Derzeit habe ich eine Sprite-Klasse mit einer StaticSprite- und DynamicSprite-Unterklasse. Ich möchte die Sprite-Klasse abstrakt machen.

Das Problem ist, dass es keine gemeinsamen Methoden gibt. Naja, sowohl StaticSprite als auch DynamicSprite können sich eine draw () - Methode teilen, aber die Parameter dieser Methode sind unterschiedlich, daher ist dies keine Option.

Danke!

BEARBEITEN: Hier ist der Code, um zu demonstrieren, was ich versuche zu tun:

Sprite:

%Vor%

Statiksprite:

%Vor%

Dynamikprite:

%Vor%

Wie Sie sehen, ist es nutzlos, ein Sprite-Objekt zu erstellen, also möchte ich diese Klasse abstrakt machen. Aber ich kann draw () abstract nicht machen, da es verschiedene Parameter verwendet.

    
Bv202 07.03.2011, 21:38
quelle

9 Antworten

15

Sie können Ihren Destruktor als rein virtuell deklarieren, da alle Klassen einen haben.

%Vor%

Sie müssen diesen Destruktor jedoch an anderer Stelle definieren.

%Vor%     
Tugrul Ates 07.03.2011, 21:41
quelle
11

Wenn die Klasse nichts tut und nichts bereitstellt und nur als Markierung existiert, gibt es keinen Grund, sich darüber Gedanken zu machen, ob sie abstrakt ist oder nicht. Dies ist im Wesentlichen ein Nicht-Problem.

Wenn Sie unbedingt sicherstellen möchten, dass eine Instanz nur im Kontext der Vererbung instanziiert wird, verwenden Sie geschützte Konstruktoren .

Bitte vermeiden Sie es, einen reinen virtuellen Destruktor zu erstellen. So liegt der Wahnsinn.

    
Randolpho 07.03.2011 21:44
quelle
3

Berücksichtigen Sie für die spezifischen Umstände Ihres Posts die private Vererbung. Auf diese Weise können Sie die Implementierung der Basis faul nutzen, ohne eine unechte IS-A-Beziehung zur Welt zu bekunden.

    
fizzer 07.03.2011 21:58
quelle
2

Nein, gibt es nicht.

Du könntest das natürlich benutzen:

%Vor%

Aber der Compiler wird sich natürlich nicht beschweren, wenn Sie versuchen, eine Instanz davon zu erstellen.

Sie können einen reinen virtuellen Destruktor hinzufügen:

%Vor%

oder Sie können den Konstruktor schützen, indem Sie die Instanziierung stoppen:

%Vor%     
Cthutu 07.03.2011 21:40
quelle
2

Die traditionelle Vorgehensweise besteht darin, einen reinen virtuellen Destruktor zu erstellen und anschließend zu implementieren.

%Vor%     
Erik 07.03.2011 21:43
quelle
2
  

Das Problem ist, dass es keine gibt   Methoden, die sie teilen.

Nun, da ist dein Problem genau dort. Sie sollten hier keine Vererbung verwenden! Wenn Sie nicht beabsichtigen, eine Klasse durch die andere zu ersetzen, sollten Sie nicht in einer Eltern-Kind-Beziehung sein.

Je nach Bedarf sollten sie völlig unabhängig voneinander sein, Vorlagen oder Komposition verwenden.

BEARBEITEN: Basierend auf dem Codebeispiel erben Sie die Wiederverwendung und ich würde stattdessen die Verwendung von Komposition empfehlen. Sprite könnte ein struct sein, das sowohl von DynamicSprite als auch von StaticSprite gehört. Sie können in Sprite entsprechend viele / kleine Hilfslogik einfügen.

    
Mark B 07.03.2011 21:46
quelle
1

Der beste Ansatz besteht darin, die Klassenkonstruktoren zu schützen. Auf diese Weise kann die Klasse nicht direkt instanziiert werden und ist daher im Wesentlichen abstrakt:

%Vor%

Oder neuerer Stil:

%Vor%

Destruktor ist im Allgemeinen besser öffentlich, weil Sie ein Objekt möglicherweise anhand seines Basisklassenzeigers löschen möchten.

    
Sergey Galin 13.04.2017 08:21
quelle
0

Um eine rein abstrakte Klasse zu erstellen, die nicht instanziiert werden kann, ohne daraus abgeleitet zu werden, müssen Sie mindestens eine abstrakte Methode definieren.

zB

%Vor%

Ansonsten können Sie jede Klasse als abstrakte Klasse verwenden

    
Martin Beckett 07.03.2011 21:41
quelle
-1

Wenn Sie wirklich die Vererbung verwenden müssen, sollten Sie das idiom der nicht virtuellen Schnittstelle (NVI) in Erwägung ziehen (siehe Ссылка )

Im Wesentlichen definiert die Basisklasse eine überladene, nicht virtuelle Menge von Methoden, die geschützte reine virtuelle Funktionen von den abgeleiteten Klassen aufrufen.

Was Sie definitiv nicht tun wollen, ist eine virtuelle Funktion zu überladen (was so aussieht, wie Sie es wirklich wollen).

    
J T 07.03.2011 22:44
quelle

Tags und Links