最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 泛型編程詳解

 更新時(shí)間:2020年02月06日 16:00:07   作者:LWL20201104  
這一篇介紹一下 C++ 編程中與面向?qū)ο蟛⒘械牧硪淮蠓种А盒途幊?,這一篇主要介紹函數(shù)模板、類模板和成員模板三大部分,需要的朋友可以參考下

泛型編程與面向?qū)ο缶幊痰哪繕?biāo)相同,即使重用代碼和抽象通用概念的技術(shù)更加簡單。但是面向?qū)ο缶幊虖?qiáng)調(diào)編程的數(shù)據(jù)方面,泛型編程強(qiáng)調(diào)的是獨(dú)立于特定數(shù)據(jù)類型。

這一篇介紹一下 C++ 編程中與面向?qū)ο蟛⒘械牧硪淮蠓种А盒途幊?,這一篇主要介紹函數(shù)模板、類模板和成員模板三大部分

如有侵權(quán),請聯(lián)系刪除,如有錯(cuò)誤,歡迎大家指正,謝謝

泛型編程

模板是泛型編程的一種重要思想,STL(Standard Template Library,標(biāo)準(zhǔn)模板庫)是采用模板實(shí)現(xiàn)的一個(gè)實(shí)例
函數(shù)模板

對比函數(shù)重載(同一作用域內(nèi)函數(shù)名相同,參數(shù)列表不同的函數(shù)),函數(shù)模板只需要一個(gè)函數(shù)就實(shí)現(xiàn)了函數(shù)重載的部分功能(參數(shù)個(gè)數(shù)相同類型不同,函數(shù)重載需要定義多個(gè)同名參數(shù)列表不同的函數(shù))

template<typename T, typename Y> // 這也可以寫 template<class T, class Y> 此處的 class 和 typename 作用相同
void tfunc(T& t, Y& y) {
 cout << t << " " << y << endl;
}
int n = 2;
double d = 2.1;
tfunc(n, d);

// 運(yùn)行結(jié)果:2 2.1

函數(shù)模板具體化,函數(shù)模板具體化就是將某一(某幾)個(gè)要處理的類型單獨(dú)處理,需要單獨(dú)寫一個(gè)實(shí)現(xiàn),形式是 template<> void fun(type& t);,函數(shù)模板的具體化和普通函數(shù)可以同時(shí)存在,調(diào)用順序是 普通函數(shù) > 函數(shù)模板具體化 > 模板函數(shù)

// ====== 測試一:函數(shù)模板針對特殊數(shù)據(jù)類型具體化 ======
struct Node {
 int val;
 Node* next;
};
// 函數(shù)模板
template<typename T> 
void tfunc(const T& t) {
 cout << "template: " << t << endl;
}
// 函數(shù)模板具體化(用于處理Node類型數(shù)據(jù))
template<> 
void tfunc<Node>(const Node& node) {
 cout << "template<Node>: " << node.val << endl;
}
// 函數(shù)模板具體化(用于處理int類型數(shù)據(jù))
template<> 
void tfunc<int>(const int& n) {
 cout << "template<int>: " << n << endl;
}
// 普通函數(shù)
void tfunc(const int& n) {
 cout << "tfunc(): " << n << endl;
}
double d = 2.1;
tfunc(d); // 函數(shù)模板未具體化double類型函數(shù),調(diào)用模板
Node node{ 2, nullptr };
tfunc(node); // 函數(shù)模板具體化Node類型函數(shù),調(diào)用函數(shù)模板的具體化
int n = 2;
tfunc(n); // 函數(shù)模板具體化int類型函數(shù),也存在普通函數(shù),調(diào)用普通函數(shù)
// ====== 測試二:函數(shù)模板部分具體化 ======
template<typename T1, typename T2>
void tfunc(T1 t1, T2 t2) {
 cout << typeid(T1).name() << " and " << typeid(T2).name() <<": " << t1 << " " << t2 << endl;
}
template<typename T1>
void tfunc(T1 t1, int i) {
 cout << typeid(T1).name() << " and " << "int: " << t1 << " " << i << endl;
}
template<typename T2>
void tfunc(long l, T2 t2) {
 cout << "long and " << typeid(T2).name() << ": " << l << " " << t2 << endl;
}
template<>
void tfunc(short l, int i) {
 cout << "long and int: " << l << " " << i << endl;
}
// 分別調(diào)用以上四個(gè)模板函數(shù)
tfunc(char('c'), char('c'));
tfunc(char('c'), int(10));
tfunc(long(10), char('c'));
tfunc(short(10), int(10));

函數(shù)模板實(shí)例化,讓編譯器生成指定類型的函數(shù)定義,不用寫函數(shù)的實(shí)現(xiàn),形式是 template void fun(type& t);

// 函數(shù)模板
template<typename T> 
void tfunc(const T& t) {
 cout << "template: " << t << endl;
}

// 函數(shù)模板實(shí)例化,不用寫函數(shù)的實(shí)現(xiàn),編譯器會生成該類型的模板具體化函數(shù)
template void tfunc<char>(const char& c);

類模板

類模板可以指定默認(rèn)模板參數(shù)(函數(shù)模板不可以),跟函數(shù)參數(shù)的默認(rèn)值一樣,必須從右向左連續(xù)賦值默認(rèn)類型,如果實(shí)例化對象時(shí)又傳遞了類型,默認(rèn)類型會被覆蓋掉,跟函數(shù)參數(shù)是一樣的
創(chuàng)建對象時(shí)需要傳遞模板參數(shù)列表,模板參數(shù)列表加在類名后面 ClassName< typename T > classN; 如果類的模板參數(shù)列

表有默認(rèn)值,可以不傳模板參數(shù),但一定要加 <> 如 ClassName< > classN; 創(chuàng)建堆區(qū)對象的時(shí)候,所有的類名稱后面都要加模板參數(shù)列表,如 ClassName< typename T >* classN = new ClassName< typename T>; 除了類內(nèi),其他地方出現(xiàn) ClassName 的地方一般都要加模板參數(shù)列表

template<typename T = int, typename Y = char> // 此處指定了模板默認(rèn)參數(shù),部分指定必須從右到左指定
class Test {
public:
 Test(T t, Y y) : t(t), y(y) {
 }
 void tfunc();
private:
 T t;
 Y y;
};
template<typename T, typename Y> // 類模板的函數(shù)在類外實(shí)現(xiàn),需要加上模板參數(shù)列表,但不需要加指定的默認(rèn)模板參數(shù)
void Test<T, Y>::tfunc() { // 類外使用Test需要加模板參數(shù)
 cout << t << " " << y << endl;
}
int n = 2;
double d = 2.1;
Test<int, double> test(n, d); // 此處如果使用默認(rèn)模板參數(shù)可定義為 Test<> test(int(2), char('a'));
test.tfunc();
// 運(yùn)行結(jié)果:2 2.1

類模板的繼承,類模板被繼承后參數(shù)的傳遞方式主要有兩種,一種是直接在子類繼承父類的時(shí)候,為父類指定固定的類型,二是通過子類模板參數(shù)列表傳遞

// ====== 測試一 ======
template<typename T, typename Y>
class A {
public:
 A(T t, Y y) {
 }
};
class Test : public A<int, double> { // 父類是類模板,子類是普通類
public:
 Test() : A<int, double>(2, 2.1) {
 }
};
Test();
// ====== 測試二 ======
template<typename T, typename Y>
class A {
public:
 A(T t) {
 }
};
template<typename X, typename Z, typename P>
class Test : public A<X, P> {
public:
 Test(X x, Z z, P p) : A<X, P>(x) {
 }
};
Test<int, double, char>(int(2), double(2.1), char('a'));

類模板的多態(tài),在創(chuàng)建對象時(shí),分為子類沒有模板(CFather<short, char>*cf = new CSon;)和子類有模板(CFather<short, char> *cf = new CSon<short, int, char>)兩種,子類和父類的模板參數(shù)列表可以不一樣,但一定要對應(yīng)好

// ====== 測試一 ======
template<typename T, typename Y> 
class A {
public:
 virtual void tfunc(T t, Y y) = 0;
};
class Test : public A<int, double> { 
public:
 virtual void tfunc(int n, double d) {
 cout << n << " " << d << endl;
 }
};
// 父類是類模板,子類是普通類,在多態(tài)情況下父類需要指定模板參數(shù),子類就不用了
A<int, double>* a = new Test;
a->tfunc(2, 2.1);
// 運(yùn)行結(jié)果:2 2.1
// ====== 測試二 ======
template<typename T, typename Y> 
class A {
public:
 virtual void tfunc(T t, Y y) = 0;
};
template<typename X, typename Z, typename P>
class Test : public A<X, P> {
public:
 virtual void tfunc(X x, P p) {
 cout << x << " " << p << endl;
 }
};

// 父類是類模板,子類是類模板,在多態(tài)情況下父類和子類都需要指定模板參數(shù)
A<int, double>* a = new Test<int, char, double>;
a->tfunc(2, 2.1);
// 運(yùn)行結(jié)果:2 2.1

類模板具體化,類模板的具體化分為部分具體化和全部具體化兩種

template<typename T1, typename T2>
class Test {
public:
 Test() {
 cout << "T1 and T2" << endl;
 }
};
// 部分具體化
template<typename T1>
class Test<T1, int> {
public:
 Test() {
 cout << "T1 and int" << endl;
 }
};
// 部分具體化
template<typename T2>
class Test<long, T2> {
public:
 Test() {
 cout << "long and T2" << endl;
 }
};
// 全部具體化
template<>
class Test<long, int> {
public:
 Test() {
 cout << "long and int" << endl;
 }
};
// 分別創(chuàng)建上面四個(gè)類
Test<char, char>();
Test<char, int>();
Test<long, char>();
Test<long, int>();

成員模板

成員模板簡單說就是模板中的模板

class Base1 { };
class Base2 { };
class Test1 : public Base1 { };
class Test2 : public Base2 { };
template<typename T1, typename T2> 
class Pair {
public:
 T1 t1;
 T2 t2;
 Pair(T1 t1, T2 t2) : t1(t1), t2(t2) {
 }
 // 類模板中的成員模板
 template<typename U1, typename U2>
 Pair(const Pair<U1, U2>& pair) : t1(pair.t1), t2(pair.t2){
 }
};
Pair<Base1*, Base2*>(Pair<Test1*, Test2*>(new Test1, new Test2));

如果未特殊說明,以上測試均是在win10 vs2017 64bit編譯器下進(jìn)行的

總結(jié)

以上所述是小編給大家介紹的C++ 泛型編程,希望對大家有所幫助!

相關(guān)文章

  • 輕松實(shí)現(xiàn)C/C++各種常見進(jìn)制相互轉(zhuǎn)換

    輕松實(shí)現(xiàn)C/C++各種常見進(jìn)制相互轉(zhuǎn)換

    這篇文章主要介紹了輕松實(shí)現(xiàn)C/C++各種常見進(jìn)制相互轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • C++實(shí)現(xiàn)LeetCode(116.每個(gè)節(jié)點(diǎn)的右向指針)

    C++實(shí)現(xiàn)LeetCode(116.每個(gè)節(jié)點(diǎn)的右向指針)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(116.每個(gè)節(jié)點(diǎn)的右向指針),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++模擬Linux Shell編寫一個(gè)自定義命令

    C++模擬Linux Shell編寫一個(gè)自定義命令

    這篇文章主要介紹了C++如何模擬Linux Shell實(shí)現(xiàn)編寫一個(gè)自定義命令,本文通過實(shí)例代碼進(jìn)行命令行解析,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 基于C語言實(shí)現(xiàn)圖書管理信息系統(tǒng)設(shè)計(jì)

    基于C語言實(shí)現(xiàn)圖書管理信息系統(tǒng)設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了基于C語言實(shí)現(xiàn)圖書管理信息系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 利用C語言模擬實(shí)現(xiàn)qsort,strcpy,strcat,strcmp函數(shù)

    利用C語言模擬實(shí)現(xiàn)qsort,strcpy,strcat,strcmp函數(shù)

    這篇文章主要為大家詳細(xì)介紹了如何通過C語言模擬實(shí)現(xiàn)qsort(采用冒泡的方式),strcpy,strcat,strcmp等函數(shù),文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-11-11
  • Qt QTreeWidget 樹形結(jié)構(gòu)實(shí)現(xiàn)代碼

    Qt QTreeWidget 樹形結(jié)構(gòu)實(shí)現(xiàn)代碼

    Qt中實(shí)現(xiàn)樹形結(jié)構(gòu)可以使用QTreeWidget類,也可以使用QTreeView類,QTreeWidget繼承自QTreeView類,接下來通過本文給大家介紹Qt QTreeWidget 樹形結(jié)構(gòu)實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2021-11-11
  • C++中為何推薦要把基類析構(gòu)函數(shù)設(shè)置成虛函數(shù)

    C++中為何推薦要把基類析構(gòu)函數(shù)設(shè)置成虛函數(shù)

    這篇文章主要介紹了C++中為何推薦要把基類析構(gòu)函數(shù)設(shè)置成虛函數(shù)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 利用C語言玩轉(zhuǎn)魔方陣實(shí)例教程

    利用C語言玩轉(zhuǎn)魔方陣實(shí)例教程

    這篇文章主要給大家介紹了關(guān)于利用C語言玩轉(zhuǎn)魔方陣的相關(guān)資料,文中詳細(xì)介紹了關(guān)于奇數(shù)魔方陣和4N 魔方陣的實(shí)現(xiàn)方法,通過示例代碼讓大家更好的參考學(xué)習(xí),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • C語言 單向鏈表的增刪查改快速掌握

    C語言 單向鏈表的增刪查改快速掌握

    單向鏈表特點(diǎn)是鏈表的鏈接方向是單向的,訪問要通過順序讀取從頭部開始。鏈表是使用指針構(gòu)造的列表,是由一個(gè)個(gè)結(jié)點(diǎn)組裝起來的,又稱為結(jié)點(diǎn)列表。其中每個(gè)結(jié)點(diǎn)都有指針成員變量指向列表中的下一個(gè)結(jié)點(diǎn),head指針指向第一個(gè)結(jié)點(diǎn)稱為表頭,而終止于最后一個(gè)指向nuLL的指針
    2021-11-11
  • QT中刪除信號于槽的連接的實(shí)現(xiàn)

    QT中刪除信號于槽的連接的實(shí)現(xiàn)

    本文主要介紹了QT中刪除信號于槽的連接的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06

最新評論

项城市| 武宁县| 任丘市| 右玉县| 兴仁县| 邹城市| 石屏县| 台南市| 汤原县| 公安县| 宝兴县| 宁南县| 桂东县| 乐业县| 衡南县| 中方县| 安化县| 岱山县| 临夏县| 安国市| 巴林左旗| 玉环县| 乳源| 许昌县| 临安市| 彩票| 左贡县| 漯河市| 镇江市| 西盟| 丰顺县| 延庆县| 莱阳市| 和田县| 信丰县| 黎平县| 海林市| 冕宁县| 保亭| 建宁县| 邛崃市|