泛型語義
泛型(Generic Programming),即是指具有在多種數據類型上皆可操作的含意。泛型編
程的代表作品 STL 是一種高效、泛型、可交互操作的軟件組件。
泛型編程最初誕生於 C++中,目的是為了實現 C++的 STL(標准模板庫)。其語言支
持機制就是模板(Templates)。
模板的精神其實很簡單:類型參數化(type parameterized),即,類型也是一種參數,
也是一種靜多態。 換句話說, 把一個原本特定於某個類型的算法或類當中的類型信息抽掉,
抽出來做成模板參數。
stack類
Stack 類模板化,可以 push 和 pop 不同的數據類型。主要由幾個因素需要把控。棧
中的空間元素類型,壓入元素類型,彈出元素類型,三者保持一致即可。
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std;
class Stack{
public: Stack(int size=1024){ space = new int[size]; top = 0; }
~Stack(){ delete []space; }
bool isEmpty(){ return top == 0; }
bool isFull(){ return top == 1024; }
void push(int data){ space[top++] = data; }
int pop(){ return space[--top]; } private: int* space; int top; }; int main() { Stack s(100); for(int i=0; i<10; ++i){ if(!s.isFull()) s.push(i); }
while(!s.isEmpty()) cout<<s.pop()<<endl; return 0; }
類模板
格式:
應用:
ClassName<int> cn; //類模板->模板類->類對象
Stack類模板
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std;
template<typename T>class Stack {
public: Stack(int size=1024); ~Stack(); bool isEmpty(); bool isFull(); void push(T data); T pop();
private:
T* space; int top; };
template<typename T> Stack<T>::Stack(int size) { space = new T[size]; top = 0; }
template<typename T> Stack<T>::~Stack(){ delete []space; }
template<typename T>bool Stack<T>::isEmpty(){ return top == 0; }
template<typename T>bool Stack<T>::isFull(){ return top == 1024; }
template<typename T>void Stack<T>::push(T data){ space[top++] = data; }
template<typename T> T Stack<T>::pop(){ return space[--top]; }
int main() { Stack<string> s(100); for(int i=0; i<10; ++i){ if(!s.isFull()) s.push(to_string(i)+"-abc"); }
while(!s.isEmpty()) cout<<s.pop()<<endl; return 0; }
類的模板本質上就是函數模板的應用,將抽象化的函數租組織到一個類 模板 內,類名的本質就是一個命名空間。
template<typename T> class XXX從格式上區別於類,完成了對類進行抽象。
類模板的友元
#include <iostream> #include <istream> #include <ostream> using namespace std; //類內實現友元 template<typename T> class Complex { friend istream & operator>> (istream & in, Complex<T>& c) { in>>c.real>>c.image; return in; }
friend ostream & operator<< (ostream & out, Complex<T> & c) { cout<<"("<<c.real<<","<<c.image<<")"<<endl; return out; } private: T real; T image; }; int main() { Complex<double> c; cin>>c; cout<<c; return 0; }
類外實現友元
1 )類前聲明
2 )friend 類中聲明 <>
3 )類外實現
#include <iostream> #include <istream> #include <ostream>
using namespace std;
//①類前聲明
template<typename T> class Complex; template<typename T> istream & operator>> (istream & in, Complex<T>& c); template<typename T> ostream & operator<< (ostream & out, Complex<T> & c);
template<typename T> class Complex {
//②freind類中聲明<> friend istream & operator>> <>(istream & in, Complex<T>& c); friend ostream & operator<< <>(ostream & out, Complex<T> & c); private: T real; T image; };
//③類外實現
template<typename T> istream & operator>> (istream & in, Complex<T>& c) { in>>c.real>>c.image; return in; }
template<typename T> ostream & operator<< (ostream & out, Complex<T> & c)
{
cout<<"("<<c.real<<","<<c.image<<")"<<endl;
return out;
}
int main() { Complex<double> c; cin>>c; cout<<c; return 0; }
hpp
《C++編程思想》第 15 章(第 300 頁):
模板定義很特殊。由 template<…> 處理的任何東西都意味着編譯器在當時不為它分
配存儲空間, 它一直處於等待狀態直到被一個模板實例告知。 在編譯器和連接器的某一處,
有一機制能去掉指定模板的多重定義。所以為了容易使用,幾乎總是在頭文件中放置全部
的模板聲明和定義,文件后綴為.hpp。