Templates in C ++

C ++ ist ein Beispiel für eine stark typisierte Programmiersprache. Es ist diese stark typisierte-ness, die Funktionen überlastet werden können, wie im folgenden Codeausschnitt gezeigt:

Menu

Leere Klasse (Student) -Lücke Grad (Land) -Lücke fn (Student e) {Grad (en) -}

C ++ hat keine Probleme mit dem Verständnis, dass der Anruf zu Klasse (n) sollte an die Funktion gerichtet Klasse (Student).

Starke Typisierung Kräfte Methoden werden überlastet, die die gleiche an der C ++ Ebene erscheinen, sind aber ganz anders bei der Umsetzung wie im folgenden Beispiel:

int vergleichen (int l, int r) {return (l> r)? 1: (l lt; r)? -1: 0-} int vergleichen (Doppel l, Doppel r) {return (l> r)? 1: (l lt; r)? -1: 0-}

Dies vergleichen() liefert eine 1, wenn die linke, Hand Argument größer als das rechte, Hand, eine -1, wenn die linke; Hand Argument kleiner als das Recht, Hand, und eine 0, wenn sie gleich sind. Trotz der Ähnlichkeit des Quellcodes, der Maschinencode durch diese beiden Funktionen erzeugt wird, sehr unterschiedlich sind, aufgrund von Unterschieden in der Art, dass int umgesetzt wird gegen doppelt auf der Maschinenebene.

Der Präprozessor bietet eine Möglichkeit, solche redundante Implementierungen zu vermeiden:

#define COMPARE (l, r) (((l)> (r)) 1:? (? (L) lt; (r)) -1: 0)

Jedoch leidet diese aus einer Reihe von ernsthaften Einschränkungen - nicht die geringste davon ist die Notwendigkeit für die Funktion in einem Ausdruck zu passen (in der Tat in einer Zeile). Darüber hinaus können Fehler in einem Präprozessormakro zu Problemen führen, die nur schwer zu debuggen sind.

Funktionsschablonen

Die Vorlage Funktion in C ++ ermöglicht dem Programmierer die Vorteile starke Typisierung und vermeiden die Einschränkungen des Vorprozessors unter Verwendung eines Platzhalter für den Typ beizubehalten. Die folgenden definiert vergleichen() für einige unbestimmte Klasse T werden später genannt:

Vorlage  T vergleichen (T l, T r) {return (l> r)? 1: (l lt; r)? -1: 0-}

Eine solche Definition ist als ein bekannter Funktionsschablone. Diese Funktion template - dessen vollständiger Name vergleichen(T, T) - kann durch die Zufuhr in eine reale Funktion umgewandelt werden T:

Vorlage Doppel vergleichen(Double, double) -

Sie können auch zulassen C ++, die Klasse zu finden und instanziiert T für Sie, entweder durch eine teilweise Erklärung bzw. unter Verwendung der Funktion wie im folgenden Beispiel Codeausschnitt gezeigt:

Vorlage Doppel vergleichen (double, double) -int main () {cout lt; lt; Vergleichen (0, 0) lt; lt; "" Lt; lt; Vergleichen (1.0, 2.0) lt; lt; Endl-return 0-}

Hier kann die Funktion Vergleichen (double, double) wird durch die ursprüngliche Erklärung, auch ohne die zusätzliche nach dem Funktionsnamen erstellt. Die Funktion Vergleichen (int, int) erstellt wird, wenn es in der Anweisung verwendet wird Vergleichen (0, 0).

Class-Vorlagen

Die C ++ Template-Funktion ermöglicht es Klassen-Typen verwendet werden definiert, die später angegeben werden. Dies löst eine Reihe von Problemen in einem bauart sicher. Ein Problem, wenn auch längst nicht das einzige Problem ist, dass der generischen Containern. (EIN Container ist eine Klasse, die Objekte einer anderen Klasse hält.)

In den frühen Tagen von C ++, der einzige Weg, eine generische Container-Klasse zu schaffen, war auf der generischen verlassen Leere Zeiger (der Zeiger der Klasse Leere*). Ähnlich wie die #definieren "Funktion" weiter oben erwähnt, ist dieser Ansatz wichen effektiv C ++ 's starke Typisierung Mechanismus mit Aussagen wie die folgenden:

Klasse Container {public: void add (void *) - void * get () - // ... andere Mitglieder ...} - Klasse Container-Leere storeStudent (Student e) {container.add ((void *) e) -} Schüler * getStudent () {return (Student *) container.get () -}

C ++ Vorlagen erlauben es dem Programmierer eine Klasse-Vorlage zu definieren, in denen ein oder mehrere Typen nicht angegeben ist, bis die Klasse verwendet wird:

Vorlage  Klasse Container {public: void put (T * p) -T * get () -} -

In der Praxis muss die Klassenvorlage zunächst in eine echte Klasse umgewandelt werden, indem ein Typ für die Versorgung T. Es kann dann in voller Typsicherheit verwendet werden:

Container Container-Schüler s-container.put (n) -Student * pS = container.get () -

Es gibt keine Notwendigkeit, Ihre eigenen Container Klassen- der Standard Template Library bietet eine Reihe solcher Klassen zu definieren. Beispielsweise erstellt der folgende Code-Schnipsel eine verknüpfte Liste von Zeigern auf Schüler Objekte und fügt einen an das Ende der Liste:

// muss enthalten 
am Anfang der Module sList-Schüler * pS = new Student () - sList.push_back (en) -

Viele der Klassen, die Sie jeden Tag verwenden, sind in der Tat, instantiations von Klassen-Templates. Das häufigste Beispiel ist, wenn Istream und ostream sind für Standard-Ein- und Ausgabe.

Iteratoren

Obwohl sie nicht direkt Teil der Vorlagenfunktion sind, Iteratoren bieten eine standardisierte Möglichkeit, die verschiedenen Arten von Behältern in der Standard Template Library zuzugreifen. Alle Behälter stellen ein Verfahren, das einen Iterator zum Anfang des Behälters und eine Möglichkeit der Überprüfung zurückgibt, wenn der Iterator am Ende des Behälters (dies schließt ungeordneten Behältern, für die "Anfang" und "Ende" ist ein statistisches Konzept). Der Iterator selbst stellt mindestens zwei Verfahren: eines das aktuelle Objekt und einer zurück den Iterator zum nächsten Objekt zu vermeiden.

Der folgende Code durch durch eine Sammlung von Zeigern auf Schüler Objekte. Der gleiche Code funktioniert unabhängig davon, welche eine der vielen Arten von Behältern Sie verwenden:

// DisplayAllStudents - iterieren durch eine Liste von // Studenten- aufrufen, um die toString () // Methode auf eachvoid displayAllStudents (Liste sList) {for (auto iter = sList.begin (!) - iter = sList.end () - iter ++) {Schüler * pS = * iter-cout lt; lt; pS-> toString () lt; lt; endl-}}

(In diesem Beispiel wird davon ausgegangen, dass die Klasse Schüler umfasst ein Verfahren bespannen() dass gibt eine Zeichendarstellung eines Schülers.)

Diese Funktion verwendet die Start() Methode einen Iterator zurückzugeben, an dem ersten Teil des Behälters zeigt. Die Funktion iteriert durch den Behälter, bis die Iterator Punkte Ende() der sich auf das Element nach dem letzten Element in dem Behälter. Der Inkrementoperator bewegt den Iterator auf das nächste Mitglied in dem Behälter, während der * Operator gibt das Objekt an der Iterator hingewiesen.

Das Auto Stichwort sagt erklären iter des Typs zurückgegeben werden durch sList.begin (). Dies ist eine Erweiterung für C ++ durch den 2011-Standard hinzugefügt. Ohne Auto, Ich hätte erklärt iter sein Typ Liste::const_Iterator.

Menü