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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++模板的注意事项

發(fā)布時間:2024/7/23 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++模板的注意事项 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

函數(shù)模板

template <typename T> //把typename換成class也可以

函數(shù)模板調(diào)用方法

使用過程中, 有兩種方法調(diào)用, 如下:

  • 自動類型推導(dǎo):
#include <iostream>template <class T> void swap(T &first, T &second) {T temp;temp = first;first = second;second = temp; }int main() {int a = 10;int b = 20;swap(a, b);return 0; }
  • 顯示指定類型
#include <iostream>template <class T> void swap(T &first, T &second) {T temp;temp = first;first = second;second = temp; }int main() {int a = 10;int b = 20;swap<int>(a, b);return 0; }

注意, 兩者的區(qū)別在于調(diào)用時是否傳入模板類型.

函數(shù)模板調(diào)用規(guī)則

  • 普通函數(shù)調(diào)用時可以發(fā)生隱式類型轉(zhuǎn)換
  • 函數(shù)模板, 用自動類型推導(dǎo), 不能發(fā)生隱式類型轉(zhuǎn)換
  • 函數(shù)模板, 用顯示指定類型, 可以發(fā)生隱式類型轉(zhuǎn)換?

普通函數(shù)和函數(shù)模板調(diào)用順序規(guī)則

假設(shè)有以下例子:

#include <iostream> using namespace std;void mSwap(int &first, int &second) {cout << "call normal function" << endl;int temp;temp = first;first = second;second = temp; }template <class T> void mSwap(T &first, T &second) {cout << "call template function" << endl;T temp;temp = first;first = second;second = temp; }
  • 如果函數(shù)模板和普通函數(shù)都可以調(diào)用, 優(yōu)先調(diào)用普通函數(shù)

示例代碼:

int main() {int a = 10;int b = 20;mSwap(a, b);return 0; }

結(jié)果:

?

  • 可以通過空模板參數(shù)列表強制調(diào)用函數(shù)模板

示例:

int main() {int a = 10;int b = 20;mSwap<>(a, b);return 0; }

結(jié)果:

  • 函數(shù)模板可以發(fā)生函數(shù)重載

比如又加了一個函數(shù):

template <class T> void mSwap(T &first, T &second) {cout << "call template function" << endl;T temp;temp = first;first = second;second = temp; }template <class T> void mSwap(T &first, T &second, T &third) {cout << "call template function" << endl;T temp;temp = first;first = second;second = temp; }

現(xiàn)在就有兩個同名函數(shù)模板了, 這樣傳入三個參數(shù)就會調(diào)用下面的.?

  • 如果函數(shù)模板可以產(chǎn)生更好的匹配(不需要發(fā)生隱式類型轉(zhuǎn)換), 優(yōu)先調(diào)用函數(shù)模板

比如有如下調(diào)用:

int main() {char a = 'a';char b = 'b';mSwap(a, b);return 0; }

運行結(jié)果為:

函數(shù)模板局限性

比如有如下代碼:

class People { public:People(string name, int age) : m_name(name), m_age(age) {}string m_name;int m_age; };template <class T> bool mCompare(const T &a, const T &b) {if (a == b)return true;elsereturn false; }

?當(dāng)有如下調(diào)用時:

int main() {People p1("michael", 18);People p2("michael", 18);mCompare(p1, p2);return 0; }

會發(fā)生如下編譯錯誤:

出現(xiàn)以上情況我們當(dāng)然可以在類中實現(xiàn)" == "的運算符重載, 也可以用如下的方法, 在以上代碼的基礎(chǔ)上增加以下代碼:

template<> bool mCompare(const People &a, const People &b) {if (a.m_name == b.m_name &&a.m_age == b.m_age)return true;elsereturn false; }

這樣即對以上的函數(shù)模板進行people定制化重載。

類模板

在類的聲明按照如下聲明:

template <class nameType, class ageType> class People { public:People(nameType name, ageType age) : m_name(name), m_age(age) {}nameType m_name;ageType m_age; };

這樣使用的時候按照如下使用:

int main() {People<string, int> p1("michael", 18);return 0; }

類模板中成員函數(shù)創(chuàng)建時機

類模板中成員函數(shù)在調(diào)用時才創(chuàng)建.

如下測試代碼:

class People1 { public:void showPerple1(){cout << "this is class People1" << endl;} };class People2 { public:void showPerple2(){cout << "this is class People2" << endl;} };template <class T> class mClass { public:void show1() {m_obj.showPerple1();}void show2() {m_obj.showPerple2();}T m_obj; };

如上代碼是可以編譯通過的.

如下測試代碼:

int main() {mClass <People1> p1;mClass <People2> p2;p1.show1();p2.show2();return 0; }

?編譯時候確定了T的類型之后, 如果發(fā)現(xiàn)T中沒有成員函數(shù)中的函數(shù), 就會報錯.

類模板的對象作函數(shù)參數(shù)

假設(shè)有如下模板類:

template <class nameType, class ageType> class People { public:People(const nameType &name, const ageType &age) : m_name(name), m_age(age) {}void show() {cout << "name: " << m_name << endl;cout << "age: " << m_age << endl;}nameType m_name;ageType m_age; };

如果想要調(diào)用People實例化對象的show函數(shù), 可以有以下方法:

  • 指定傳入類型

方法如下:

void showPeople1(People<string, int> &p) {p.show(); }int main() {People<string, int> p1("michael", 18);showPeople1(p1);return 0; }
  • 參數(shù)模板化

方法如下:

template <class nameType, class ageType> void showPeople2(People<nameType, ageType> &p) {p.show(); }int main() {People<string, int> p2("michael", 18);showPeople1(p2);return 0; }
  • 整個類模板化

方法如下:

template <class P> void showPeople3(P &p) {p.show(); }int main() {People<string, int> p3("michael", 18);showPeople3(p3);return 0; }

類模板繼承

  • 當(dāng)父類是模板類時, 子類在繼承的時候需要指定父類中的模板類型, 當(dāng)有如下代碼:
template <class T> class Father { public:T m_T; };class Son : public Father { public: };

這樣編譯會報錯, 需要改為:

template <class T> class Father { public:T m_T; };class Son : public Father<int> { public: };

這樣就可以了?

  • 也可以把子類也變成模板類, 可以按照如下操作:
template <class T> class Father { public:T m_T; };template <class T1, class T2> class Son : public Father<T2> { public:T1 m_T1; };

類外實現(xiàn)

當(dāng)有如下類:

template <class nameType, class ageType> class People { public:People(nameType name, ageType age);void showPeople();nameType m_name;ageType m_age; };

當(dāng)我們在類外實現(xiàn)其構(gòu)造函數(shù)和成員函數(shù)時, 需要按照如下方式:

//constructor template <class nameType, class ageType> People<nameType, ageType>::People(nameType name, ageType age) {m_name = name;m_age = age; }//member function template <class nameType, class ageType> void People<nameType, ageType>::showPeople() {cout << "name: " << m_name << endl;cout << "age: " << m_age << endl; }

類模板的分文件編寫

類模板與友元

函數(shù)模板和類模板的區(qū)別

  • 類模板是不存在類型推導(dǎo)的, 所以實例化對象的時候必須傳入類型.
  • 類模板是可以有默認(rèn)參數(shù)的

可參考如下代碼:

template <class nameType, class ageType = int> class People { public:People(nameType name, ageType age) : m_name(name), m_age(age) {}nameType m_name;ageType m_age; };int main() {People<string> p1("michael", 18);return 0; }

這樣是可以的.

如果兩個參數(shù)都有默認(rèn)類型, 實例化對象的時候也必須要有尖括號, 如下:?

template <class nameType = string, class ageType = int> class People { public:People(nameType name, ageType age) : m_name(name), m_age(age) {}nameType m_name;ageType m_age; };int main() {People <>p1("michael", 18);return 0; }

模板的特化

模板的設(shè)計是為了有效減少代碼量,但是某些情況,對于某種特定類型,模板就需要進行特化。

全特化和偏特化

全特化就是限定死模板實現(xiàn)的具體類型,偏特化就是如果這個模板有多個類型,那么只限定其中的一部分。

函數(shù)模板的特化

函數(shù)模板只能進行全特化不能進行偏特化,函數(shù)模板的全特化可以參照上文說的,正常函數(shù)就是相當(dāng)于對函數(shù)模板的全特化。

類模板的特化

template<typename T1, typename T2> class Test { public:Test(T1 i,T2 j):a(i),b(j){cout<<"模板類"<<endl;} private:T1 a;T2 b; };template<> class Test<int , char> { public:Test(int i, char j):a(i),b(j){cout<<"全特化"<<endl;} private:int a;char b; };template <typename T2> class Test<char, T2> { public:Test(char i, T2 j):a(i),b(j){cout<<"偏特化"<<endl;} private:char a;T2 b; };

那么下面3句依次調(diào)用類模板、全特化與偏特化:

Test<double , double> t1(0.1,0.2); Test<int , char> t2(1,'A'); Test<char, bool> t3('A',true); //依次打印: //類模板 //全特化 //偏特化

總結(jié)

以上是生活随笔為你收集整理的C++模板的注意事项的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。