Unterschied zwischen dem Auswählen einer Unterklasse über einen Vorlagenparameter oder dem Instanziieren einer Elementvariablen

8

Angenommen, ich habe eine Klasse, die verschiedene Arten von Abstandsfunktionen (euklidische Distanz usw.) verwenden kann, um Vergleiche anzustellen. Ich habe diese Funktionen als Unterklassen einer Klasse Distance implementiert:

%Vor%

Es scheint so zu sein, dass ich, um zu entscheiden, welche Art von Entfernung ich benutzen soll:

%Vor%

und instanziieren Sie es mit:

%Vor%

oder erreichen Sie dasselbe mit:

%Vor%

und instanziieren Sie es mit

%Vor%

Gibt es irgendwelche Vorteile einer Methode gegenüber der anderen?

Danke,

David

    
David Doria 07.11.2011, 19:48
quelle

4 Antworten

6

Assoziation (d. h. die Lösung ohne Vorlagen) ist vorzuziehen, da sie Ihnen mehr Flexibilität bietet, die Entfernungsimplementierung zur Laufzeit ändern, sauberere Fehlermeldungen und sauberere Objektdateien (weniger Symbole) erzeugen kann.

Auch Klassen, die aus der mit verschiedenen Typen parametrisierten Vorlage generiert werden (Entfernungsimplementierungen), werden als unterschiedliche Typen betrachtet und sind nicht austauschbar: MyClass<EuclideanDistance> ist ein anderer Typ als MyClass<MinkowskiDistance> . Dies zwingt Sie dazu, alle Funktionen, die auf MyClass templates funktionieren, auch zu machen und führt letztendlich zu größerer Komplexität ohne zusätzliche Vorteile.

Vorlagen sollten verwendet werden, wenn Sie die Typsicherheit der Sprache lockern müssen, z. B. wenn Sie eine Klasse schreiben, die mit einer Reihe von nicht verwandten -Typen arbeiten soll (nicht von einer gemeinsamen Basis abgeleitet) Klasse / Interface), die sich trotzdem ähnlich verhalten (zB haben alle eine kwak() member Funktion). Dies nennt man duck-typing : Typen sind formal nicht verwandt, aber alle weisen ähnliche Eigenschaften auf. p>

Falls Sie nicht sicherstellen können, dass alle Entfernungsimplementierungen von einer gemeinsamen Basisklasse / Schnittstelle stammen, müssen Sie möglicherweise Vorlagen verwenden. Ansonsten bevorzugen Sie eine einfache und flexible Zuordnung.

    
Adam Zalcman 07.11.2011, 20:00
quelle
4

Nun, abgesehen vom Problem der Kompilierzeit und der Laufzeit wurde der größte Unterschied durch Ihren bereits vorhandenen Code nicht zugelassen. Wenn Sie eine Vorlage verwenden, können Sie alle Typen verwenden, die eine allgemeine Operation unterstützen (z. B. getDistance), ohne dass sie derselben Hierarchie angehören müssen. Dies hätte bedeutet, dass die euklidische Entfernung und Ihre andere Klasse völlig anders sein könnten, aber dennoch in der Vorlage verwendbar sind, solange sie die Teilmenge der von der Vorlage verwendeten Elemente unterstützten.

    
John Humphreys - w00te 07.11.2011 19:55
quelle
2

Ersteres legt die Entfernungsmetrik für die Klasse zur Kompilierungszeit fest, während die zweite zur Laufzeit ausgeführt wird. Ersteres ist wahrscheinlich effizienter, weil es dem Compiler ermöglicht, Teile davon zu optimieren, während das zweite flexibler sein kann.

    
Fred Foo 07.11.2011 19:53
quelle
1

Öffentliche Vererbung bedeutet IS-A. Ist eine euklidische Dissistenz mit einer "Lorentz-Distanz" oder "Quaternion-Distanz" (oder was auch immer) in irgendeiner sinnvollen Weise interoperabel? Sind sie beide "Abstände" in dem Sinne, dass irgendein Code irgendwo glücklich ist, einen auf eine nicht-triviale Weise zu benutzen (das heißt, etwas anderes als den Wert zu drucken, usw.)? Meine Vermutung ist nein, ist es nicht.

Sie wollen also Generika, keine Vererbung. Templates sind ein einfacheres Versprechen: Zwei Dinge "sehen" sich syntaktisch aus.

    
Andy Ross 07.11.2011 19:55
quelle

Tags und Links