2016-08-29 2 views
1

Betrachten wir Reihe von abgeleiteten Klassen zum Beispiel haben, wie nachstehend aufgeführt:Vererbung und Member-Funktionen

class A 
{ 
... 
} 

class B1 : public A //there may be many B's here say, B2, B3 etc 
{ 
... 
} 
class C1 : public B1 //may be more C's as well 
{ 
... 
} 

Ich mag würde alle Objekte in einzelnen Behältern setzen, damit alle A der Typklasse sein würde.

Angenommen, ich möchte eine Klasse C1 hinzufügen, was wäre der beste Weg, dies zu erreichen? Meine Optionen wären, es in der Basisklasse A einzuführen und die benötigte Implementierung in C1 zu schreiben, oder ich könnte es in C1 einführen und dynamisches Casting machen, um darauf zuzugreifen. Welches ist bevorzugt? Ist dynamisches Gießen zu teuer? (Meine Hauptbedingung ist die Laufzeit.Ich habe ein Flag in der Basisklasse, um anzugeben, um welche Art von abgeleitetem Objekt es sich handelt, daher muss ich nicht jedes Objekt im Container dynamisch transformieren. Das Hinzufügen unnötiger Funktionen zur Basisklasse kann dazu führen ? in schlechter Befehls-Cache-Verwendung)

+4

Niemand kann Ihnen sagen, ob dynamisches Gießen "zu teuer" ist, denn was Sie sich leisten können, ist subjektiv. Da es so zu sein scheint ("Meine Hauptbedingung ist die Laufzeit"), würde ich empfehlen, beides zu tun und die Ergebnisse zu vergleichen, um zu sehen, ob es für Ihre speziellen Hardware- und Compiler-Optimierungen und Anwendungsfälle zu teuer ist externe Restriktionen und ... – Altainia

+2

Eine Schnittstelle zu breit zu machen ist schlechtes Design und so ist Downcasting, Sie könnten eine zusätzliche Sammlung mit Zeigern zu spezifischeren Schnittstellen halten. – imreal

+0

Sie könnten eine 'Variante' mit einem Besuchermuster verwenden. – AndyG

Antwort

2

Sie sagen uns nicht, den Zweck der neuen Funktion in C1, und diese wirken die Antwort, aber als grobe Richtlinien:

  • Wenn die neue Funktion ist ein allgemeines Verhalten, das Sie möglicherweise für jedes Objekt benötigen, und C1 ist der erste Benutzer, fügen Sie einfach die Schnittstelle zu A hinzu.
  • Wenn die neue Funktion auf die C Reihe von Klassen ist spezifisch aber es einige allgemeine Muster (zB Nachbearbeitung) folgen können, fügen Sie ein post_process Methode A, außer Kraft setzen es in C1 und dass Verfahren haben Rufen Sie private Implementierungsmethoden von C1 auf, um die eigentliche spezifische Nachbearbeitungsaufgabe auszuführen.
  • Wenn dies nicht der Fall ist, möchten Sie vielleicht Ihre Verwendung der Vererbung überprüfen, da es möglich ist, dass Sie damit eine andere Beziehung als die Substitution darstellen.
+0

Die neue Funktion kann nur in 'C1' aufgrund des Typs der privaten Daten ausgeführt werden es hat Zugriff auf und es wird nicht so häufig aufgerufen. – user6386155

0

Hinzufügen einer virtuellen Funktion, um Ihre Eine Basisklasse ist besser, weil:

  • Sie dynamische Umwandlung vor allem in der Leistung sensiblen Code vermeiden sollten. Siehe Performance of dynamic_cast?

  • Sie sollten Bedingungen vermeiden, um den Objekttyp zu untersuchen (z. B. A, B1 oder C1?), Bevor Sie eine typspezifische Operation ausführen. Nicht nur, weil es langsam ist, sondern auch, weil Sie jedes Mal, wenn Sie einen neuen Objekttyp (z. B. C2) hinzufügen, alle diese Bedingungen prüfen müssen, um zu sehen, ob sie aktualisiert werden müssen.