這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)C++泛型編程是什么,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
成都創(chuàng)新互聯(lián)主要從事做網(wǎng)站、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)沁縣,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220
泛型編程與面向?qū)ο缶幊痰哪繕?biāo)相同,即使重用代碼和抽象通用概念的技術(shù)更加簡單。但是面向?qū)ο缶幊虖?qiáng)調(diào)編程的數(shù)據(jù)方面,泛型編程強(qiáng)調(diào)的是獨(dú)立于特定數(shù)據(jù)類型。
介紹一下 C++ 編程中與面向?qū)ο蟛⒘械牧硪淮蠓种А盒途幊?,主要介紹函數(shù)模板、類模板和成員模板三大部分
泛型編程
模板是泛型編程的一種重要思想,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 // 這也可以寫 template 此處的 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 void tfunc(const T& t) { cout << "template: " << t << endl;}// 函數(shù)模板具體化(用于處理Node類型數(shù)據(jù))template<> void tfunc(const Node& node) { cout << "template: " << node.val << endl;}// 函數(shù)模板具體化(用于處理int類型數(shù)據(jù))template<> void tfunc(const int& n) { cout << "template: " << 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ù)模板部分具體化 ======templatevoid tfunc(T1 t1, T2 t2) { cout << typeid(T1).name() << " and " << typeid(T2).name() <<": " << t1 << " " << t2 << endl;}templatevoid tfunc(T1 t1, int i) { cout << typeid(T1).name() << " and " << "int: " << t1 << " " << i << endl;}templatevoid 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 void tfunc(const T& t) { cout << "template: " << t << endl;}// 函數(shù)模板實(shí)例化,不用寫函數(shù)的實(shí)現(xiàn),編譯器會生成該類型的模板具體化函數(shù)template void tfunc(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 // 此處指定了模板默認(rèn)參數(shù),部分指定必須從右到左指定class Test {public: Test(T t, Y y) : t(t), y(y) { } void tfunc();private: T t; Y y;};template // 類模板的函數(shù)在類外實(shí)現(xiàn),需要加上模板參數(shù)列表,但不需要加指定的默認(rèn)模板參數(shù)void Test::tfunc() { // 類外使用Test需要加模板參數(shù) cout << t << " " << y << endl;}int n = 2;double d = 2.1;Test test(n, d); // 此處如果使用默認(rèn)模板參數(shù)可定義為 Test<> test(int(2), char('a'));test.tfunc();// 運(yùn)行結(jié)果:2 2.1
類模板的繼承,類模板被繼承后參數(shù)的傳遞方式主要有兩種,一種是直接在子類繼承父類的時(shí)候,為父類指定固定的類型,二是通過子類模板參數(shù)列表傳遞
// ====== 測試一 ======templateclass A {public: A(T t, Y y) { }};class Test : public A { // 父類是類模板,子類是普通類public: Test() : A(2, 2.1) { }};Test();// ====== 測試二 ======templateclass A {public: A(T t) { }};templateclass Test : public A {public: Test(X x, Z z, P p) : A(x) { }};Test(int(2), double(2.1), char('a'));
類模板的多態(tài),在創(chuàng)建對象時(shí),分為子類沒有模板(CFather*cf = new CSon;)和子類有模板(CFather *cf = new CSon)兩種,子類和父類的模板參數(shù)列表可以不一樣,但一定要對應(yīng)好
// ====== 測試一 ======template class A {public: virtual void tfunc(T t, Y y) = 0;};class Test : public A { public: virtual void tfunc(int n, double d) { cout << n << " " << d << endl; }};// 父類是類模板,子類是普通類,在多態(tài)情況下父類需要指定模板參數(shù),子類就不用了A* a = new Test;a->tfunc(2, 2.1);// 運(yùn)行結(jié)果:2 2.1// ====== 測試二 ======template class A {public: virtual void tfunc(T t, Y y) = 0;};templateclass Test : public A {public: virtual void tfunc(X x, P p) { cout << x << " " << p << endl; }};// 父類是類模板,子類是類模板,在多態(tài)情況下父類和子類都需要指定模板參數(shù)A* a = new Test;a->tfunc(2, 2.1);// 運(yùn)行結(jié)果:2 2.1
類模板具體化,類模板的具體化分為部分具體化和全部具體化兩種
templateclass Test {public: Test() { cout << "T1 and T2" << endl; }};// 部分具體化templateclass Test {public: Test() { cout << "T1 and int" << endl; }};// 部分具體化templateclass Test {public: Test() { cout << "long and T2" << endl; }};// 全部具體化template<>class Test {public: Test() { cout << "long and int" << endl; }};// 分別創(chuàng)建上面四個(gè)類Test();Test();Test();Test();
成員模板
成員模板簡單說就是模板中的模板
class Base1 { };class Base2 { };class Test1 : public Base1 { };class Test2 : public Base2 { };template class Pair {public: T1 t1; T2 t2; Pair(T1 t1, T2 t2) : t1(t1), t2(t2) { } // 類模板中的成員模板 template Pair(const Pair& pair) : t1(pair.t1), t2(pair.t2){ }};Pair(Pair(new Test1, new Test2));
如果未特殊說明,以上測試均是在win10 vs2017 64bit編譯器下進(jìn)行的
上述就是小編為大家分享的C++泛型編程是什么了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
本文標(biāo)題:C++泛型編程是什么
標(biāo)題來源:
http://weahome.cn/article/gcihei.html