模板1.0 -- 模板基本原理
為什么需要模板
我們經常有這樣的一種使用的情形,就是我們可能需要設計一個函數,然后函數的參數可能是整形的,也可能是浮點型的,還有可能是其他的類型的,這個時候如果對于每一個類型都寫一個函數,未免有點太復雜了
我們有以下幾個方法來實現一個函數針對不同的類型都能夠實現
法一:通過函數重載實現
比如我們想要寫一個相加的函數,我們需要實現函數的重載
int Add(const int a,const int b)
{return a+b;
}
double Add(cosnt double a,const double b)
{return a+b;
}
char Add(const char a,const char )
缺點分析:
1. 一個類出現時就需要繼續重載一個函數
2. 代碼的復用率低
3. 如果一個函數只是返回值不同,函數的重載還解決不了問題
4. 如果函數的邏輯錯誤了,那么所有的函數都需要修改,麻煩
法二:使用公共的基類
我們可以將重復的代碼放在一個公共的基類,然后進行一個繼承
缺點:
1. 公共的代碼放在了基類里面就缺少了類型檢查的優點了
2. 一個簡單的函數,以后使用了繼承之后,以后維護起來麻煩
法三:使用宏函數
#define Add(a,b) ((a)+(b))
缺點:
1. 沒有了類型檢查
2. 在預處理階段就被替換掉了,不方便調試
引入模板
C++為了解決上面的問題,于是就引入了模板的使用,像下面的形式來實現Add函數的復用
template<class T>
T Add(const T& a,const T&b)
{return a+b;
}
其中我們使用class的時候,也是可以使用typename這個關鍵字的
我們在其他的地方調用這個模板函數的時候,就可以使用下面的方式進行一個調用的過程
int x = 1;
int y = 2;
double m = 1.0;
double n = 2.0;Add(x,y);
Add(m,n);
上面的兩次對模板函數的調用是不是調用的同一個函數呢,答案:不是。他們調用了不同的函數,這里引入的一個概念就是模板的實例化
我們經常聽到的一個概念是對象的實例化,就是我們拿一個類去實例化一個對象,比如我們使用下面的代碼去實例化一個string的對象
string str;
同樣的我們的模板也是有實例化的一個過程的,就是在我們調用我們函數的時候,根據我們的參數進行一個推演,比如剛剛的那個Add(x,y);這個 時候編譯器會根據參數的類型,實例化生成一個參數是整形的Add函數,然后在對他進行一個調用,這個就是簡單的實例化的過程。
所以說上面的兩次調用實際上是生成了不同的函數,然后進行的一個調用的過程
小問題
問題一:模板函數和實例函數共存
還是上面Add函數,如果我們這個時候在上面的模板函數的基礎之上又實現了一個函數,這個時候會如何調用呢
int Add(const int& a,const int& b)
{return a+b;
}
在這種情況下,如果我們有已經實例化的函數,這個時候會直接調用我們已經實例化的函數,如果沒有已經 實例化的函數,這個時候才會去找我們的模板函數,然后實例化一個函數進行一個調用的過程
問題二:模板函數和實例函數參數不匹配
還是上面的程序,我們即有了一個模板函數,又有了一個實例函數,這個時候我們在使用的時候,傳遞的參數不是兩個整形而是兩個雙精度浮點型,那么這個時候是如何調用的呢
double a = 1.0;
double b = 2.0;
Add(a,b);
這個時候會檢查我們的實例函數,但是參數的類型不匹配,所以實際上是生成了一個參數是double類型的模板函數,然后再進行函數的一個調用的過程
如果我們的參數一個是int,一個是double的,這個時候又是怎么樣的呢,由大家自己去驗證吧
這里我們還需要注意的一個問題就是,實例化函數中的第二個參數不是一個const的時候,這個時候,我們的給 我們的參數傳入的是一個double的變量的時候,會發生隱式類型的轉換的,這個時候會生成一個臨時的變量,這個臨時的變量具有常性,所以我們應該在參數上面加上一個const
問題三:模板實例化和類型檢查
我們知道我們的模板函數只有在實例化的時候,才會生成可執行代碼的,如果我們在VS下面測試的時候,編譯器是不會對模板函數的內部進行檢查的,比如我們少寫了一個分號,但是在linux下面使用g++進行 編譯的時候是會進行一個檢查的過程的
模板類
模板類也很容易實現,只不過在使用的時候,我們需要對模板類進行一個顯式的實例化的過程
template<class T>
class Arr
{public:Str():_a(a){}private:T _a;
}Arr<int> arr;
上面的調用就是一個顯式的實例化的過程
總結
以上是生活随笔為你收集整理的模板1.0 -- 模板基本原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《UNIX高级环境编程》 -- apue
- 下一篇: centos设置网络自动启动