??C++語言全盤繼承了C語言的標準庫,其中包換非常豐富的系統函式,例如輸入/輸出函式、數學函式、字串處理函式和動態記憶體分配函式等,C++語言另外又增加了一些新的庫,我們把C++語言新增的這部分庫稱為C++標準庫,C++語言的模板技術包括函式模板和類模板,模板技術是一種代碼重用技術,函式和類是C++語言中兩種主要的重用代碼形式,代碼模板使源程式更加凝練,
一、函式模板
??函式模板的基本原理是通過資料型別的引數化,將一組演算法相同但所處理資料型別不同的多載函式凝練成一個函式模板,
1、函式模板的定義和使用
??函式模板的定義語法形式:
??template <型別引數串列>
??函式型別 函式名(形參引數串列)
??{
????函式體
??}
函式模板的幾點語法細則:
- 定義函式模板以關鍵字template開頭
- 型別引數串列可以宣告一個或多個型別引數,每個型別引數以"typename 型別引數名"或"class 型別引數名"的形式宣告,型別引數之間用逗號”,“隔開,
- 函式模板的其余部分,包括函式型別、函式名、形式引數串列以及函式體,它們和普通函式的定義形式沒有什么區別,
- 使用typename和class宣告的型別引數可視為一種新的資料型別,可用來定義函式型別(即回傳值型別)、形參型別和區域變數型別,型別引數是表示資料型別的引數,再實際呼叫時可被替換成任意資料型別
示例:
#include<iostream>
using namespace std;
template <typename T> //定義函式模板Max,宣告一個型別引數T
T Max(T x,T y) //使用型別引數T定義函式型別和形參x和y的型別
{
return(x>y?x:y);
}
int main()
{
cout << Max(5,10) <<endl; //呼叫回傳最大值10
cout << Max(5.2,10.2) <<endl; //呼叫回傳最大值10.2
return 0;
}
??函式模板可以像普通函式一樣被呼叫,再呼叫者看來,函式模板的型別引數像是一種通用資料型別,
2、函式模板的編譯原理
??函式模板是具有型別引數的函式,型別引數是表示資料型別的引數,可指代任意一種實際資料型別,編譯器再編譯到函式模板的呼叫陳述句時,根據位置對應關系從實參資料型別推匯出型別引數所指代的資料型別,然后按照函式模板自動生成一個該型別的函式定義代碼,不同型別實參的函式模板呼叫陳述句將生成不同型別的多載函式,函式模板將資料型別引數化,呼叫時會呈現引數多型性,
3、函式模板的宣告
??跟普通函式一樣函式模板也需要先定義后呼叫的原則,如果函式模板定義再呼叫后,或定義再其他程式檔案中,則應先宣告后呼叫,函式模板的宣告語法形式為:
??template <型別引數串列>
??函式型別 函式名(形參引數串列);
??或
??template <型別引數串列> 函式型別 函式名(形參引數串列);
#include<iostream>
using namespace std;
template <typename T> //函式模板Max定義宣告
T Max(T x,T y);
int main()
{
cout << Max(5,10) <<endl; //函式模板Max使用
cout << Max(5.2,10.2) <<endl;
return 0;
}
template <typename T> //函式模板Max定義
T Max(T x,T y)
{
return(x>y?x:y);
}
??程式員再編程時可以靈活使用模板技術,在定義多個多載函式時可以考慮是否將他們定義成一個函式模板,這樣可以凝練函式代碼,再定義單個函式時也可以考慮定義成函式模板,這樣可以提高函式代碼的可重用性,對于呼叫函式模板的程式員而言,函式模板和普通函式沒有什么區別,唯一不同的時函式模板可以處理不同型別的資料,
二、類模板
??應用模板技術,也可以將一組功能相同但所處理資料型別不同的類凝練成一個類模板,編譯時,再由編譯器按照類模板自動生成針對不同資料型別的類定義代碼,
1、類模板的定義和使用
??定義類模板的語法形式:
??template <型別引數串列>
??class 類名 //類宣告部分
??{
????類成員宣告
??}
??//類實作部分:所有類外定義的函式成員,必須按如下的語法形式將它們定義成函式模板
??template <型別引數串列>
??函式型別 類名<型別引數名串列>::函式名(形式引數串列)
??{ 函式體 }
類模板的幾點語法細則:
- 定義類模板以關鍵字template開頭
- 型別引數串列可以宣告一個或多個型別引數,每個型別引數以"typename 型別引數名"或"class 型別引數名"的形式宣告,型別引數之間用逗號”,“隔開,
- 類模板定義的其余部分,包括類名、類成員宣告以及類實作部分,它們和普通類的定義形式基本相同,
- 定義類模板的函式成員,如果再類內定義(行內函式),其語法形式和普通類的函式成員沒區別;如果再類外(即類實作部分)定義,則必須按照函式模板的語法形式來定義,并且還要再函式名前面加“類名<型別引數名串列>::”限定,
- 使用typename和class宣告的型別引數可視為一種新的資料型別,型別引數是表示資料型別的引數,再使用類模板時可被替換成任意資料型別,
定義好的類模板可以像普通類一樣被用來定義物件,使用類模板定義物件時,需要明確給出類模板中型別引數所指代的實際資料型別,其語法形式如下:類模板名 <實際資料型別串列> 物件名1,物件名2 .....;
類模板語法示例:
| 在類內定義函式成員(行內) | 在類外定義函式模板成員 |
|
|
2、類模板的編譯原理
??當定義到類模板定義物件陳述句時,編譯器將根據所給出的實際資料型別來取代型別引數T,例如 A <double> o1(10.5,6); 編譯時將類模板中型別別引數系結到某個具體資料型別的程序,稱為類模板的實體化,實體化所生成的類稱為類模板的實體類,實體類是一個普通的類,可以用來定義物件,
??類模板編譯原理:類模板是具有型別引數的類,型別引數是表示資料型別的引數,可指代任意實際資料型別,編譯器在編譯到使用類模板定義物件陳述句時,將首先按照所給定的實際資料型別對類模板進行實體化,生成一個實體類,最終,編譯器使用實體類來定義所需要的物件,
3、類模板的繼承和派生
??類模板可以被繼承,派生出新類,以類模板為基類定義派生類,可以在派生時實體化,也可以繼續定義派生類模板,
1、定義實體化派生類
??定義實體化派生類就是在派生類繼承基類的時候將型別引數賦值,此時派生類對基類進行實體化,
實體化派生類示例
#include<iostream>
using namespace std;
template <typename T> //類模板基類Base
class Base //類宣告部分
{
private: //宣告私有資料成員
T a;
public:
Base(T x) { a=x; }
void Show() { cout<< "a="<<a<<","; }
};
//無類實作部分
class Derived:public Base<double> //公有繼承基類模板Base,派生時實體化
{
private: //宣告新增資料成員
int b;
public:
//注意派生類建構式寫法
Derived(double p1,int p2):Base<double>(p1) { b=p2; }
//新增函式成員Show
void Show() { Base <double>::Show(); cout<< "b="<<b<<endl; }
};
int main()
{
Derived obj(10.5,6);//定義派生類Derived物件obj
obj.Show(); //顯示結果:a=10.5,b=6
return 0;
}
??在編譯到派生類Derived的定義代碼時,編譯器將按照所給定的實際資料型別double對類模板Base進行實體化,生成一個double型的實體類,最終派生類Derived繼承的是該實體類,
2、定義派生類模板
??定義派生類模板是派生類在繼承類模板基類時不進行實體化,因此派生類仍然是一個類模板,
派生類模板示例
#include<iostream>
using namespace std;
template <typename T> //類模板基類Base
class Base //類宣告部分
{
private: //宣告私有資料成員
T a;
public:
Base(T x) { a=x; }
void Show() { cout<< "a="<<a<<","; }
};
//無類實作部分
//公有繼承類模板Base,派生類仍為類模板
template <typename T,typename TT> //新增型別引數TT
class Derived:public Base<T> //公有繼承基類模板Base,定義派生類模板
{
private: //宣告新增資料成員
TT b;
public:
//注意派生類建構式寫法
Derived(T p1,TT p2):Base<T>(p1) { b=p2; }
//新增函式成員Show
void Show() { Base <T>::Show(); cout<< "b="<<b<<endl; }
};
int main()
{
Derived<double,int> obj(10.5,6);//定義派生類Derived物件obj
obj.Show(); //顯示結果:a=10.5,b=6
return 0;
}
??和其他類模板一樣,派生類模板Derived在定義物件時需要明確給出派生類模板中型別引數所指代的實際資料型別,程式員編程時,在定義多個功能相同但處理資料型別不同的類時應考慮是否可以將它們合并成一個類模板,這樣可以凝練代碼,再定義單個類時也可以考慮升級成類模板,這樣可以提高函式代碼的可重用性,對于呼叫類模板的程式員而言,類模板和普通類沒有什么區別,只是在使用類模板時需要給出型別引數所指代的實際資料型別,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500396.html
標籤:其他
上一篇:IOS OpenGL ES GPUImage GPUImageDirectionalNonMaximumSuppressionFilter
