C++-Vorlage

黄舟
Freigeben: 2016-12-13 14:31:07
Original
1376 Leute haben es durchsucht

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;
}
Nach dem Login kopieren

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;
Nach dem Login kopieren

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"
Nach dem Login kopieren
//method.cpp

template<typename  T> void swap(T& t1, T& t2) {
    T tmpT;
    tmpT = t1;
    t1 = t2;
    t2 = tmpT;
}
Nach dem Login kopieren

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;
}
Nach dem Login kopieren
Klassenvorlage

Stellen Sie sich vor, wir schreiben eine einfache Stapelklasse. Dieser Stapel kann den Typ int, den Typ long, den Typ string usw. unterstützen. Ohne Klassenvorlagen müssen wir drei Codes schreiben Die obige Stapelklasse ist im Grunde dieselbe. Über die Klassenvorlage können wir eine einfache Stapelvorlage definieren und sie dann je nach Bedarf als Int-Stack, Long-Stack oder String-Stack instanziieren.

Das Obige definiert eine Klassenvorlage – einen Stapel. Er dient nur zur Veranschaulichung der Verwendung der Klassenvorlage. Er kann nur bis zu 100 Elemente auf dem Stapel unterstützen . Das Verwendungsbeispiel lautet wie folgt:
//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"
Nach dem Login kopieren
//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;
}
Nach dem Login kopieren

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;
}
Nach dem Login kopieren


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{...}
Nach dem Login kopieren

Verwendungsbeispiele sind wie folgt:
//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"
Nach dem Login kopieren
//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;
}
Nach dem Login kopieren

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;
}
Nach dem Login kopieren
Wenn wir verschiedene Implementierungen von definieren möchten Als Vorlage können wir die Vorlagenspezialisierung verwenden. Wenn es sich beispielsweise bei der von uns definierten Stapelklassenvorlage um einen Stapel vom Typ char* handelt, hoffen wir, alle Daten von char in die Stapelklasse zu kopieren, da nur der char-Zeiger gespeichert wird und der Speicher, auf den der char-Zeiger zeigt kann ungültig werden und das vom Stapel angezeigte Stapelelement Der Speicher, auf den der char-Zeiger zeigt, ist möglicherweise ungültig. Es gibt auch die von uns definierte Auslagerungsfunktionsvorlage. Wenn das vom Container gespeicherte Objekt groß ist, belegt es viel Speicher und verringert die Leistung, da ein temporäres großes Objekt generiert werden muss Um ein Problem zu lösen, ist eine Spezialisierung erforderlich.

Spezialisierung von Funktionsvorlagen

Angenommen, unsere Swap-Funktion möchte eine Situation bewältigen. Wir haben zwei Vektoren und führen tmpT = aus t1 muss alle Elemente von t1 kopieren, was viel Speicher beansprucht und zu Leistungseinbußen führt. Daher löst unser System dieses Problem durch die Funktion vector.swap. Der Code lautet wie folgt:

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"
Nach dem Login kopieren
#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);
}
Nach dem Login kopieren

vector begrenzt. Wenn Sie die Vorlagenspezialisierung verwenden möchten, um den Austausch aller Vektoren zu lösen, müssen Sie nur den folgenden Code

//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;
}
Nach dem Login kopieren

in

template<> void swap(std::vector<int>& t1, std::vector<int>& t2) {
    t1.swap(t2);
}
Nach dem Login kopieren
<🎜 ändern >

Die anderen Codes bleiben unverändert.

Klassenvorlagenspezialisierung
template<class V> void swap(std::vector<V>& t1, std::vector<V>& t2) {
    t1.swap(t2);
}
Nach dem Login kopieren

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;
  }
};
Nach dem Login kopieren
#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;
 }
Nach dem Login kopieren
Die Datei main.cpp bleibt unverändert und dieser Code kann normal funktionieren.

Vorlagentypkonvertierung
//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;
    }
};
Nach dem Login kopieren

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 {
};
Nach dem Login kopieren
Dann hoffen wir, es so zu verwenden:


Dies kann nicht kompiliert werden, da Stack nicht die übergeordnete Klasse von Stack , aber wir möchten, dass der Code so funktioniert, dann müssen wir den Stack-Code wie folgt definieren:

//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;
}
Nach dem Login kopieren
Nach dem Login kopieren

Auf diese Weise ist Stack< ;Circle> oder Stack kann automatisch in Stack konvertiert werden.
//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"
Nach dem Login kopieren
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;
}
Nach dem Login kopieren
Andere
//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;
}
Nach dem Login kopieren
Nach dem Login kopieren

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;
}
Nach dem Login kopieren

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage