C++ 除了支援函式模板,還支援類模板(Class Template)。函式模板中定義的型別引數可以用在函式宣告和函式定義中,類模板中定義的型別引數可以用在類宣告和類實現中。類模板的目的同樣是將資料的型別引數化。一起來學習一下吧!
宣告類模板的語法為:
template
//TODO:
};
類模板和函式模板都是以 template 開頭(當然也可以使用 class,目前來講它們沒有任何區別),後跟型別引數;型別引數不能為空,多個型別引數用逗號隔開。
一但聲明瞭類模板,就可以將型別引數用於類的成員函式和成員變量了。換句話說,原來使用 int、float、char 等內建型別的地方,都可以用型別引數來代替。
假如我們現在要定義一個類來表示座標,要求座標的資料型別可以是整數、小數和字串,例如:
x = 10、y = 10
x = 12.88、y = 129.65
x = "東京180度"、y = "北緯210度"
這個時候就可以使用類模板,請看下面的程式碼:
template
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
返回值型別 類名<型別引數1 ...="">::函式名(形參列表){
//TODO:
}
第一行是模板頭,第二行是函式頭,它們可以合併到一行,不過為了讓程式碼格式更加清晰,一般是將它們分成兩行。
下面就對 Point 類的成員函式進行定義:
template
T1 Point
return m_x;
}
template
void Point
m_x = x;
}
template
T2 Point
return m_y;
}
template
void Point
m_y = y;
}
請讀者仔細觀察程式碼,除了 template 關鍵字後面要指明型別引數,類名 Point 後面也要帶上型別引數,只是不加 typename 關鍵字了。另外需要注意的是,在類外定義成員函式時,template 後面的型別引數要和類宣告時的一致。
使用類模板建立物件
上面的兩段程式碼完成了類的定義,接下來就可以使用該類建立物件了。使用類模板建立物件時,需要指明具體的資料型別。請看下面的程式碼:
Point
Point
Point
與函式模板不同的是,類模板在例項化時必須顯式地指明資料型別,編譯器不能根據給定的資料推演出資料型別。
除了物件變數,我們也可以使用物件指標的方式來例項化:
Point
Point
需要注意的.是,賦值號兩邊都要指明具體的資料型別,且要保持一致。下面的寫法是錯誤的:
//賦值號兩邊的資料型別不一致
Point
//賦值號右邊沒有指明資料型別
Point
綜合示例
將上面的類定義和類例項化的程式碼整合起來,構成一個完整的示例,如下所示:
#include
using namespace std;
template
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
T1 Point
return m_x;
}
template
void Point
m_x = x;
}
template
T2 Point
return m_y;
}
template
void Point
m_y = y;
}
int main(){
Point
cout<<"x="<<()<<", y="<<()<<endl;
Point
cout<<"x="<<()<<", y="<<()<<endl;
Point
cout<<"x="<
return 0;
}
執行結果:
x=10, y=20
x=10, y=東京180度
x=東京180度, y=北緯210度
在定義型別引數時我們使用了 class,而不是 typename,這樣做的目的是讓讀者對兩種寫法都熟悉。