2012-05-11 3 views
8

Hallo, ich habe alle Zweifel bezüglich Templates und Polymorphie. 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.Was ist der Unterschied zwischen Templates und Polymorphie

+1

Vorlagen bieten statischen/Kompilierzeit-Polymorphismus. Während * Virtualismus * dynamischen Polymorphismus bietet. –

+1

Was ist anders? Alles. Der Polymorphismus steht nicht einmal im entferntesten über die Wiederverwendbarkeit von Code. Vorlagen sind. –

+1

@MooingDuck: Polymorphismus erlaubt Code-Wiederverwendung. Alter Code (geschrieben gegen eine polymorphe Basisklasse) unter Verwendung von neuem Code (geschrieben in dieselbe Basisklasse). –

Antwort

11

Sie scheinen zu verstehen, was Polymorphismus ist.

Der Polymorphismus hat im 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 aus 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 beliebige Klasseninstanzen, die von der Basisklasse abgeleitet sind.

Compile-Zeit Polymorphismus Polymorphismus ist, die ... bei der Kompilierung geschieht;) Was dies bedeutet, ist, dass der Compiler muss wissen, was los ist. Möglicherweise haben Sie den C++ - Code für einen polymorphen Prototyp geschrieben, aber dem Compiler ist das egal. Sie erhalten bestimmte 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 durch den Typ durch die Vorlage Funktion/Klasse definiert definiert.

Wenn Sie diese Vorlage Funktion haben:

template<typename T> 
void Stuff(T &t) 
{ 
    t.call(15); 
} 

Es gibt eine implizite Anforderung an T. Diese Anforderung besteht darin, dass es eine Elementfunktion namens call hat. Es muss eine einzelne Überladung dieser Member-Funktion geben, die mit einem Integer-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 moreso wenn Ihre Vorlage Prototyp ist gut gestaltet:

template<typename T> 
void Stuff(T &t) 
{ 
    call(t, 15); 
} 

Alles, was diese Version von Stuff ist es erforderlich, dass es eine Funktion ist, die einen T& und einen ganzzahligen Wert annimmt. 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. Alle ohne Modifizierung der Typ selbst.

Natürlich, Kompilierzeit Polymorphismus ist ... 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 es präziser über seine Prototypen ist. Ü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 führt eine anständige IDE Ihren Code, so dass Sie nur die Methoden der Basisklasse sehen.

Template Polymorphie ist viel mehr implizit. Da C++ keine Möglichkeit hat, den Prototyp, den eine bestimmte Template-Funktion/Klasse einem Typ hinzufügt, zu schreiben, ist es sehr einfach, etwas versehentlich auf einem Template-Typ aufzurufen, den Sie nicht tun sollten. Der Compiler erkennt dies nur, wenn Sie versuchen, einen Typ zu verwenden, der nicht zum Prototyp passt. Und selbst dann erhalten Sie im Allgemeinen 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, die implizite Vorlage polymorphe Prototyp zu implementieren, da es nicht buchstabiert ist. 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 einen Fehler, der in der Regel weniger als das Problem ist.

+1

"Es muss eine einzelne Überladung dieser Elementfunktion geben, die mit einem ganzzahligen Wert aufgerufen werden kann." - und dieser Aufruf mit "int" darf nicht mehrdeutig sein und möglicherweise eine andere Bedingung, die ich vergessen habe. Aus diesem Grund wird der polymorphe Prototyp in der Regel als "Dieser Ausdruck muss folgende Eigenschaften haben: ..." dokumentiert. Wenn Sie versuchen, es zu dokumentieren, welche Funktionen und Überladungen * existieren, dann geraten Sie in alle möglichen Randfälle. –

Verwandte Themen