Funktionsvorlage
Beim Einstieg in C++ werden viele Leute mit swap(int&, Der ähnliche Code für eine Funktion wie int&) lautet wie folgt:
void swap(int&a , int& b) { int temp = a; a = b; b = temp; }
Aber wenn Sie Long-, String- und benutzerdefinierte Klassenaustauschfunktionen unterstützen möchten, ähnelt der Code dem obigen Code, jedoch vom Typ Zu diesem Zeitpunkt definieren wir die Swap-Funktionsvorlage. Sie können verschiedene Arten von Swap-Funktionscodes wiederverwenden. Die Deklarationsform der Funktionsvorlage lautet wie folgt:
template <class identifier> function_declaration; template <typename identifier> function_declaration;
Der Deklarations- und Definitionscode der Die Swap-Funktionsvorlage lautet wie folgt:
//method.h template<typename T> void swap(T& t1, T& t2); #include "method.cpp"
//method.cpp template<typename T> void swap(T& t1, T& t2) { T tmpT; tmpT = t1; t1 = t2; t2 = tmpT; }
Das Obige ist die Deklaration und Definition der Vorlage. Die Instanziierung der Vorlage erfolgt durch den Compiler und hat nichts damit zu tun Wie verwende ich die obige Vorlage? . Dies unterscheidet sich von der allgemeinen Funktionsverwendung. Daher muss #include zur letzten Zeile der Datei method.h hinzugefügt werden „method.cpp“.
//main.cpp #include <stdio.h> #include "method.h" int main() { //模板方法 int num1 = 1, num2 = 2; swap<int>(num1, num2); printf("num1:%d, num2:%d\n", num1, num2); return 0; }
//statck.h template <class T> class Stack { public: Stack(); ~Stack(); void push(T t); T pop(); bool isEmpty(); private: T *m_pT; int m_maxSize; int m_size; }; #include "stack.cpp"
//stack.cpp template <class T> Stack<T>::Stack(){ m_maxSize = 100; m_size = 0; m_pT = new T[m_maxSize]; } template <class T> Stack<T>::~Stack() { delete [] m_pT ; } template <class T> void Stack<T>::push(T t) { m_size++; m_pT[m_size - 1] = t; } template <class T> T Stack<T>::pop() { T t = m_pT[m_size - 1]; m_size--; return t; } template <class T> bool Stack<T>::isEmpty() { return m_size == 0; }
Vorlagenparameter
Eine Vorlage kann Typparameter, reguläre Typparameter int oder Standardvorlagenparameter wie//main.cpp #include <stdio.h> #include "stack.h" int main() { Stack<int> intStack; intStack.push(1); intStack.push(2); intStack.push(3); while (!intStack.isEmpty()) { printf("num:%d\n", intStack.pop()); } return 0; }
haben Die oben genannten Klassenvorlagen Der Stapel hat eine Einschränkung, das heißt, er kann nur maximal 100 Elemente unterstützen. Wir können Vorlagenparameter verwenden, um die maximale Anzahl von Elementen dieses Stapels zu konfigurieren . Der Code lautet wie folgt:
template<class T, T def_val> class Stack{...}
//statck.h template <class T,int maxsize = 100> class Stack { public: Stack(); ~Stack(); void push(T t); T pop(); bool isEmpty(); private: T *m_pT; int m_maxSize; int m_size; }; #include "stack.cpp"
//stack.cpp template <class T,int maxsize> Stack<T, maxsize>::Stack(){ m_maxSize = maxsize; m_size = 0; m_pT = new T[m_maxSize]; } template <class T,int maxsize> Stack<T, maxsize>::~Stack() { delete [] m_pT ; } template <class T,int maxsize> void Stack<T, maxsize>::push(T t) { m_size++; m_pT[m_size - 1] = t; } template <class T,int maxsize> T Stack<T, maxsize>::pop() { T t = m_pT[m_size - 1]; m_size--; return t; } template <class T,int maxsize> bool Stack<T, maxsize>::isEmpty() { return m_size == 0; }
Vorlagenspezialisierung
//main.cpp #include <stdio.h> #include "stack.h" int main() { int maxsize = 1024; Stack<int,1024> intStack; for (int i = 0; i < maxsize; i++) { intStack.push(i); } while (!intStack.isEmpty()) { printf("num:%d\n", intStack.pop()); } return 0; }
template<> Präfix bedeutet, dass es sich um eine Spezialisierung handelt, für deren Beschreibung keine Vorlagenparameter erforderlich sind. Das Verwendungsbeispiel lautet wie folgt:
//method.h template<class T> void swap(T& t1, T& t2); #include "method.cpp"
#include <vector> using namespace std; template<class T> void swap(T& t1, T& t2) { T tmpT; tmpT = t1; t1 = t2; t2 = tmpT; } template<> void swap(std::vector<int>& t1, std::vector<int>& t2) { t1.swap(t2); }
vector
//main.cpp #include <stdio.h> #include <vector> #include <string> #include "method.h" int main() { using namespace std; //模板方法 string str1 = "1", str2 = "2"; swap(str1, str2); printf("str1:%s, str2:%s\n", str1.c_str(), str2.c_str()); vector<int> v1, v2; v1.push_back(1); v2.push_back(2); swap(v1, v2); for (int i = 0; i < v1.size(); i++) { printf("v1[%d]:%d\n", i, v1[i]); } for (int i = 0; i < v2.size(); i++) { printf("v2[%d]:%d\n", i, v2[i]); } return 0; }
in
template<> void swap(std::vector<int>& t1, std::vector<int>& t2) { t1.swap(t2); }
Die anderen Codes bleiben unverändert.
template<class V> void swap(std::vector<V>& t1, std::vector<V>& t2) { t1.swap(t2); }
Bitte sehen Sie sich den Vergleichscode unten an:
Beim Vergleich zweier Ganzzahlen ist die Gleichheitsmethode des Vergleichs korrekt, aber vergleichen Sie Wann Der Vorlagenparameter ist char*, die Vorlage funktioniert nicht, daher ist die Änderung wie folgt:
//compare.h template <class T> class compare { public: bool equal(T t1, T t2) { return t1 == t2; } };
#include <iostream> #include "compare.h" int main() { using namespace std; char str1[] = "Hello"; char str2[] = "Hello"; compare<int> c1; compare<char *> c2; cout << c1.equal(1, 1) << endl; //比较两个int类型的参数 cout << c2.equal(str1, str2) << endl; //比较两个char *类型的参数 return 0; }
//compare.h #include <string.h> template <class T> class compare { public: bool equal(T t1, T t2) { return t1 == t2; } }; template<>class compare<char *> { public: bool equal(char* t1, char* t2) { return strcmp(t1, t2) == 0; } };
Erinnern Sie sich noch an unsere angepasste Stack-Vorlage? In unserem Programm lautet der Code wie folgt:
//shape.h class Shape { }; class Circle : public Shape { };
//main.cpp #include <stdio.h> #include "stack.h" #include "shape.h" int main() { Stack<Circle*> pcircleStack; Stack<Shape*> pshapeStack; pcircleStack.push(new Circle); pshapeStack = pcircleStack; return 0; }
//statck.h template <class T> class Stack { public: Stack(); ~Stack(); void push(T t); T pop(); bool isEmpty(); template<class T2> operator Stack<T2>(); private: T *m_pT; int m_maxSize; int m_size; }; #include "stack.cpp"
template <class T> Stack<T>::Stack(){ m_maxSize = 100; m_size = 0; m_pT = new T[m_maxSize]; } template <class T> Stack<T>::~Stack() { delete [] m_pT ; } template <class T> void Stack<T>::push(T t) { m_size++; m_pT[m_size - 1] = t; } template <class T> T Stack<T>::pop() { T t = m_pT[m_size - 1]; m_size--; return t; } template <class T> bool Stack<T>::isEmpty() { return m_size == 0; } template <class T> template <class T2> Stack<T>::operator Stack<T2>() { Stack<T2> StackT2; for (int i = 0; i < m_size; i++) { StackT2.push((T2)m_pT[m_size - 1]); } return StackT2; }
//main.cpp #include <stdio.h> #include "stack.h" #include "shape.h" int main() { Stack<Circle*> pcircleStack; Stack<Shape*> pshapeStack; pcircleStack.push(new Circle); pshapeStack = pcircleStack; return 0; }
Eine Klasse hat keine Vorlagenparameter, aber die Mitgliedsfunktion hat Vorlagenparameter. Der Code lautet wie folgt:
Sie können sogar Wenn Sie Util gleich als statisch deklarieren, lautet der Code wie folgt:class Util { public: template <class T> bool equal(T t1, T t2) { return t1 == t2; } }; int main() { Util util; int a = 1, b = 2; util.equal<int>(1, 2); return 0; }