日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++类模板5分钟入门

發布時間:2025/3/15 c/c++ 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++类模板5分钟入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考自http://c.biancheng.net/view/2318.html

C++ 除了支持函數模板,還支持類模板(Class Template)。函數模板中定義的類型參數可以用在函數聲明和函數定義中,類模板中定義的類型參數可以用在類聲明和類實現中。類模板的目的同樣是將數據的類型參數化。
聲明類模板的語法為:

template<typename 類型參數1 , typename 類型參數2 , …> class 類名{
? ? //TODO:
};

類模板和函數模板都是以 template 開頭(當然也可以使用 class,目前來講它們沒有任何區別),后跟類型參數;類型參數不能為空,多個類型參數用逗號隔開。
一但聲明了類模板,就可以將類型參數用于類的成員函數和成員變量了。換句話說,原來使用 int、float、char 等內置類型的地方,都可以用類型參數來代替。
假如我們現在要定義一個類來表示坐標,要求坐標的數據類型可以是整數、小數和字符串,例如:

  • x = 10、y = 10
  • x = 12.88、y = 129.65
  • x = "東經180度"、y = "北緯210度"

這個時候就可以使用類模板,請看下面的代碼:

template<typename T1, typename T2> //這里不能有分號 class Point{ public:Point(T1 x, T2 y): m_x(x), m_y(y){ } public:T1 getX() const; //獲取x坐標void setX(T1 x); //設置x坐標T2 getY() const; //獲取y坐標void setY(T2 y); //設置y坐標 private:T1 m_x; //x坐標T2 m_y; //y坐標 };

x 坐標和 y 坐標的數據類型不確定,借助類模板可以將數據類型參數化,這樣就不必定義多個類了。

注意:模板頭和類頭是一個整體,可以換行,但是中間不能有分號。

上面的代碼僅僅是類的聲明,我們還需要在類外定義成員函數。在類外定義成員函數時仍然需要帶上模板頭,格式為:

template<typename 類型參數1 , typename 類型參數2 , …>
返回值類型 類名<類型參數1 , 類型參數2, ...>::函數名(形參列表){
? ? //TODO:
}

第一行是模板頭,第二行是函數頭,它們可以合并到一行,不過為了讓代碼格式更加清晰,一般是將它們分成兩行。

下面就對 Point 類的成員函數進行定義:

template<typename T1, typename T2> //模板頭 T1 Point<T1, T2>::getX() const /*函數頭*/ {return m_x; }template<typename T1, typename T2> void Point<T1, T2>::setX(T1 x){m_x = x; }template<typename T1, typename T2> T2 Point<T1, T2>::getY() const{return m_y; }template<typename T1, typename T2> void Point<T1, T2>::setY(T2 y){m_y = y; }

請讀者仔細觀察代碼,除了 template 關鍵字后面要指明類型參數,類名 Point 后面也要帶上類型參數,只是不加 typename 關鍵字了。另外需要注意的是,在類外定義成員函數時,template 后面的類型參數要和類聲明時的一致。

使用類模板創建對象

上面的兩段代碼完成了類的定義,接下來就可以使用該類創建對象了。使用類模板創建對象時,需要指明具體的數據類型。請看下面的代碼:

Point<int, int> p1(10, 20); Point<int, float> p2(10, 15.5); Point<float, char*> p3(12.4, "東經180度");

與函數模板不同的是,類模板在實例化時必須顯式地指明數據類型,編譯器不能根據給定的數據推演出數據類型。

除了對象變量,我們也可以使用對象指針的方式來實例化:

Point<float, float> *p1 = new Point<float, float>(10.6, 109.3); Point<char*, char*> *p = new Point<char*, char*>("東經180度", "北緯210度");

需要注意的是,賦值號兩邊都要指明具體的數據類型,且要保持一致。下面的寫法是錯誤的:

//賦值號兩邊的數據類型不一致 Point<float, float> *p = new Point<float, int>(10.6, 109); //賦值號右邊沒有指明數據類型 Point<float, float> *p = new Point(10.6, 109);

綜合示例

【實例1】將上面的類定義和類實例化的代碼整合起來,構成一個完整的示例,如下所示:

#include <iostream> using namespace std;template<class T1, class T2> //這里不能有分號 class Point{ public:Point(T1 x, T2 y): m_x(x), m_y(y){ } public:T1 getX() const; //獲取x坐標void setX(T1 x); //設置x坐標T2 getY() const; //獲取y坐標void setY(T2 y); //設置y坐標 private:T1 m_x; //x坐標T2 m_y; //y坐標 };template<class T1, class T2> //模板頭 T1 Point<T1, T2>::getX() const /*函數頭*/ {return m_x; }template<class T1, class T2> void Point<T1, T2>::setX(T1 x){m_x = x; }template<class T1, class T2> T2 Point<T1, T2>::getY() const{return m_y; }template<class T1, class T2> void Point<T1, T2>::setY(T2 y){m_y = y; }int main(){Point<int, int> p1(10, 20);cout<<"x="<<p1.getX()<<", y="<<p1.getY()<<endl;Point<int, char*> p2(10, "東經180度");cout<<"x="<<p2.getX()<<", y="<<p2.getY()<<endl;Point<char*, char*> *p3 = new Point<char*, char*>("東經180度", "北緯210度");cout<<"x="<<p3->getX()<<", y="<<p3->getY()<<endl;return 0; }

運行結果:
x=10, y=20
x=10, y=東經180度
x=東經180度, y=北緯210度

在定義類型參數時我們使用了 class,而不是 typename,這樣做的目的是讓讀者對兩種寫法都熟悉。

【實例2】用類模板實現可變長數組。

#include <iostream> #include <cstring> using namespace std; template <class T> class CArray {int size; //數組元素的個數T *ptr; //指向動態分配的數組 public:CArray(int s = 0); //s代表數組元素的個數CArray(CArray & a);~CArray();void push_back(const T & v); //用于在數組尾部添加一個元素vCArray & operator=(const CArray & a); //用于數組對象間的賦值T length() { return size; }T & operator[](int i){//用以支持根據下標訪問數組元素,如a[i] = 4;和n = a[i]這樣的語句return ptr[i];} }; template<class T> CArray<T>::CArray(int s):size(s) {if(s == 0)ptr = NULL;elseptr = new T[s]; } template<class T> CArray<T>::CArray(CArray & a) {if(!a.ptr) {ptr = NULL;size = 0;return;}ptr = new T[a.size];memcpy(ptr, a.ptr, sizeof(T ) * a.size);size = a.size; } template <class T> CArray<T>::~CArray() {if(ptr) delete [] ptr; } template <class T> CArray<T> & CArray<T>::operator=(const CArray & a) { //賦值號的作用是使"="左邊對象里存放的數組,大小和內容都和右邊的對象一樣if(this == & a) //防止a=a這樣的賦值導致出錯return * this;if(a.ptr == NULL) { //如果a里面的數組是空的if( ptr )delete [] ptr;ptr = NULL;size = 0;return * this;}if(size < a.size) { //如果原有空間夠大,就不用分配新的空間if(ptr)delete [] ptr;ptr = new T[a.size];}memcpy(ptr,a.ptr,sizeof(T)*a.size); size = a.size;return *this; } template <class T> void CArray<T>::push_back(const T & v) { //在數組尾部添加一個元素if(ptr) {T *tmpPtr = new T[size+1]; //重新分配空間memcpy(tmpPtr,ptr,sizeof(T)*size); //拷貝原數組內容delete []ptr;ptr = tmpPtr; }else //數組本來是空的ptr = new T[1];ptr[size++] = v; //加入新的數組元素 } int main() {CArray<int> a;for(int i = 0;i < 5;++i)a.push_back(i);for(int i = 0; i < a.length(); ++i)cout << a[i] << " "; return 0; }

?

總結

以上是生活随笔為你收集整理的C++类模板5分钟入门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。