Hallo, ich habe Zweifel bezüglich Templates und Polymorphismus. Per Definition bietet der Polymorphismus die Wiederverwendbarkeit von Code, und Vorlagen ermöglichen es dem Benutzer in gewisser Weise, den gleichen Code zu verwenden, indem er generische Programmierung mit verschiedenen Datentypen bereitstellt. Was ist der Vorteil der Verwendung von Polymorphie gegenüber Vorlagen? Es könnte eine dumme Frage sein, aber ich bin neugierig, den genauen Unterschied zu kennen.
Sie scheinen zu verstehen, was Polymorphismus ist.
Polymorphismus hat in seinem Kern nichts mit abgeleiteten Klassen zu tun. Polymorphismus bedeutet einfach die Fähigkeit, einen Typ zu benutzen, ohne alles darüber zu wissen. Anstatt einen konkreten Typ zu verwenden, beruht der Polymorphismus auf einer Form von Prototyp, um zu definieren, welche Typen er benötigt. Alle Typen, die zu diesem Prototyp passen, werden akzeptiert.
Der Laufzeitpolymorphismus in C ++ wird durch Ableiten von Klassen von einer Basisklasse bereitgestellt, die virtuelle Funktionen enthält. Die Basisklasse und die virtuellen Funktionen bilden den polymorphen Prototyp. Code, der zum Akzeptieren der Basisklasse geschrieben wird, die diese virtuellen Funktionen aufruft, akzeptiert jede Klasseninstanz, die von der Basisklasse abgeleitet ist.
Kompilierzeit Polymorphie ist Polymorphie, die passiert ... zur Kompilierzeit;) Das bedeutet, dass der Compiler wissen was vor sich geht. Möglicherweise haben Sie den C ++ - Code für einen polymorphen Prototyp geschrieben, aber dem Compiler ist das egal. Sie erhalten spezifische konkrete Arten nach der Kompilierung.
Der Kompilierzeitpolymorphismus wird durch Vorlagen in C ++ bereitgestellt. Eine Template-Funktion oder -Klasse kann einen beliebigen Typ annehmen, der einem Prototyp entspricht, der üblicherweise als "Konzept" bezeichnet wird. Im Gegensatz zu Basisklassen und virtuellen Funktionen ist der Prototyp implizit : Der Prototyp wird nur dadurch definiert, wie der Typ verwendet wird durch die Template-Funktion / Klasse.
Wenn Sie diese Vorlagenfunktion haben:
%Vor% Es gibt eine implizite Anforderung für T
. Diese Voraussetzung ist, dass es eine Elementfunktion namens call
hat. Es muss eine einzelne Überladung dieser Elementfunktion geben, die mit einem ganzzahligen Wert aufgerufen werden kann.
Dies bedeutet, dass jeder -Typ, der zufällig zu diesem Prototyp passt, verwendet werden kann.
Der Template-Polymorphismus ist breiter als der Vererbungs-Polymorphismus, da er von einer breiteren Typenreihe verwendet werden kann. Ein Typ muss spezifisch entworfen werden, um Vererbungspolymorphismus zu verwenden; Sie müssen von einer Klasse ableiten. Ein Typ kann nicht-destruktiv sein (dh Sie müssen den Typ nicht selbst ändern), der an den Template-Polymorphismus angepasst ist. Auch wenn Ihr Vorlagen-Prototyp gut gestaltet ist:
%Vor% Alles, was diese Version von Stuff
benötigt, ist, dass es eine Funktion gibt, die ein T&
und einen ganzzahligen Wert benötigt. Wenn ich einen Typ habe, den ich mit Stuff
verwenden möchte, muss ich nur eine call
-Funktion in einem geeigneten Namespace definieren (nämlich dem Namespace, in dem der Typ definiert wurde). Und das wird gut funktionieren. Alles ohne ändern den Typ selbst.
Natürlich ist der Kompilierzeit-Polymorphismus ... Kompilierzeit. Wenn eine Benutzereingabe oder eine Datendatei den polymorphen Typ auswählen soll, werden Vorlagen nicht sehr hilfreich sein (obwohl das Löschen von Daten, eine vorlagenbasierte Technik, hilfreich sein kann). Der Hauptvorteil von Laufzeit-Polymorphismus ist, dass es in der Tat Laufzeit ist.
Ein weiterer Vorteil ist, dass die Prototypen genauer sind. Über Vererbung wird ausdrücklich alles gesagt. Die virtuelle Funktionsschnittstelle in einer Basisklasse ist übersichtlich. Der Compiler wird Sie davon abhalten, diese Basisklasse falsch zu verwenden (Aufruf von Methoden, die nicht darauf existieren). In der Tat wird eine anständige IDE Ihren Code leiten, so dass Sie nur die Methoden auf der Basisklasse sehen werden.
Der Template-Polymorphismus ist viel mehr implizit. Da C ++ keine Möglichkeit hat, den Prototyp, den eine bestimmte Schablonenfunktion / -klasse einem Typ hinzufügt, zu schreiben, ist es sehr einfach, etwas versehentlich auf einem Schablonentyp aufzurufen, den Sie nicht verwenden sollten. Der Compiler erkennt dies nur, wenn Sie versuchen, einen Typ zu verwenden, der nicht zum Prototyp passt. Und selbst dann erhalten Sie normalerweise einen massiven Fehler (abhängig davon, wie tief der Template-Code verschachtelt ist), was es schwierig macht zu wissen, wo das Problem liegt.
Es ist auch viel schwieriger, den impliziten Template-Polymorph-Prototyp zu implementieren, da er nicht genau beschrieben wird. Das Implementieren einer abgeleiteten Klasse erfordert das Durchlaufen der Basisklasse, das Betrachten aller virtuellen Funktionen und ihre Implementierung. Dies für einen Template-Prototyp zu tun ist viel schwieriger, es sei denn, es gibt Dokumentation irgendwo, die es buchstabiert. Wenn Sie etwas nicht implementieren, erhalten Sie erneut eine Fehlermeldung, die in der Regel weniger als das Problem ist.
Tags und Links c++ templates polymorphism