-
重載函數(overload function)
-
在C語言中,不允許函數有同名函數,C++通過重載函數名來避免這類麻煩。你可以在同一個程序裏使用同名的兩個或多個函數。函數名重載可以讓函數使用起來更“自然”。使用了重載的程序也更容易讀和寫。
-
C++中聲明重載的函數跟聲明其它函數沒什麼不同。只不過它跟其它的某個函數重名。重載函數必須使用不同的變量,否則編譯器沒法區分它們。
-
編譯器無法通過函數不同的返回類型來區別重載函數
-
當編譯器遇到對函數put的調用,它會選擇函數參數完全匹配的函數聲明進行調用。這個過程叫做重載決策
-
有可能會有多個重載函數能夠匹配一個函數調用。
-
當面對多個可選函數時,重載決策根據函數參數類型的隱式轉換來排序,找出最匹配的那個。
-
void f(int i); void f(long int li); void f(char *p); void f(double d, int i);
對如上的程序,如果輸入int k=f(0);第一二三均符合規範,但第二三個需要強制轉換格式,所以選擇第一個。假設 void f(int)併爲被聲明,那麼二三的優先序相同。當重載決策沒有辦法選出一個最優匹配,那麼調用就是不明確的,這會產生一個編譯錯誤
-
-
模板(template)
- 模板有模板函數和模板類,定義方式如下:
定義: template <class identifier> function() {/函數主體/}; template <typename identifier> function() {/函數主體/}; 聲明: template <class identifier> function(); template <typename identifier> function();
模板的實例化是編譯器做的事情,與程序員無關
-
類模板的使用
-
//statck.h template <class T> class Stack { public: Stack(); ~Stack(); void push(T t); T pop(); bool isEmpty(); private: T *m_pT; int m_maxSize; int m_size; }; #include "stack.cpp"
//stack.cpp template <class T> Stack<T>::Stack(){ m_maxSize = 100; m_size = 0; m_pT = new T[m_maxSize]; } template <class T> Stack<T>::~Stack() { delete [] m_pT ; } template <class T> void Stack<T>::push(T t) { m_size++; m_pT[m_size - 1] = t; } template <class T> T Stack<T>::pop() { T t = m_pT[m_size - 1]; m_size--; return t; } template <class T> bool Stack<T>::isEmpty() { return m_size == 0; }
注意:對於函數模板而言不存在 h(int,int) 這樣的調用,不能在函數調用的參數中指定模板形參的類型,對函數模板的調用應使用實參推演來進行,即只能進行 h(2,3) 這樣的調用,或者int a, b; h(a,b)。
-
類模板對象的創建:比如一個模板類A,則使用類模板創建對象的方法爲A<int> m;在類A後面跟上一個<>尖括號並在裏面填上相應的類型,這樣的話類A中凡是用到模板形參的地方都會被int 所代替。當類模板有兩個模板形參時創建對象的方法爲A<int, double> m;類型之間用逗號隔開。
-
模板的聲明或定義只能在全局,命名空間或類範圍內進行。即不能在局部範圍,函數內進行,比如不能在main函數中聲明或定義一個模板。
-
模板的形參(三種類型的模板形參:類型形參,非類型形參和模板形參)
-
類型模板形參:類型形參由關見字class或typename後接說明符構成,如template<class T> void h(T a){};其中T就是一個類型形參,類型形參的名字由用戶自已確定。模板形參表示的是一個未知的類型。模板類型形參可作爲類型說明符用在模板中的任何地方,與內置類型說明符或類類型說明符的使用方式完全相同,即可以用於指定返回類型,變量聲明等。
針對函數模板 :不能爲同一個模板類型形參指定兩種不同的類型,比如 template<typename T>void h(T a, T b){},語句調用h(2, 3.2)將出錯,因爲該語句給同一模板形參T指定了兩種類型,第一個實參2把模板形參T指定爲int,而第二個實參3.2把模板形參指定爲double,兩種類型的形參不一致,會出錯。
針對於類模板:當我們聲明類對象爲:A<int> a,比如template<class T>T g(T a, T b){},語句調用a.g(2, 3.2)在編譯時不會出錯,但會有警告,因爲在聲明類對象的時候已經將T轉換爲int類型,而第二個實參3.2把模板形參指定爲double,在運行時,會對3.2進行強制類型轉換爲3。當我們聲明類的對象爲:A<double> a,此時就不會有上述的警告,因爲從int到double是自動類型轉換
-
-
模板的特例化
-
-
非類型形參
-
非類型模板形參:模板的非類型形參也就是內置類型形參,如template<class T, int a> class B{};其中int a就是非類型的模板形參。
-
非類型形參在模板定義的內部是常量值,也就是說非類型形參在模板的內部是常量。
-
非類型模板的形參只能是整型,指針和引用,像double,String, String **這樣的類型是不允許的。但是double &,double *,對象的引用或指針是正確的。
-
調用非類型模板形參的實參必須是一個常量表達式,即他必須能在編譯時計算出結果。
-
注意:任何局部對象,局部變量,局部對象的地址,局部變量的地址都不是一個常量表達式,都不能用作非類型模板形參的實參。全局指針類型,全局變量,全局對象也不是一個常量表達式,不能用作非類型模板形參的實參。
-
全局變量的地址或引用,全局對象的地址或引用const類型變量是常量表達式,可以用作非類型模板形參的實參。
-
、sizeof表達式的結果是一個常量表達式,也能用作非類型模板形參的實參。
-
當模板的形參是整型時調用該模板時的實參必須是整型的,且在編譯期間是常量,比如template <class T, int a> class A{};如果有int b,這時A<int, b> m;將出錯,因爲b不是常量,如果const int b,這時A<int, b> m;就是正確的,因爲這時b是常量。
-
非類型形參一般不應用於函數模板中,比如有函數模板template<class T, int a> void h(T b){},若使用h(2)調用會出現無法爲非類型形參a推演出參數的錯誤,對這種模板函數可以用顯示模板實參來解決,如用h<int, 3>(2)這樣就把非類型形參a設置爲整數3。顯示模板實參在後面介紹。
-
非類型模板形參的形參和實參間所允許的轉換
-
允許從數組到指針,從函數到指針的轉換。如:template <int *a> class A{}; int b[1]; A<b> m;即數組到指針的轉換
-
const修飾符的轉換。如:template<const int *a> class A{}; int b; A<&b> m; 即從int *到const int *的轉換。
-
提升轉換。如:template<int a> class A{}; const short b=2; A<b> m; 即從short到int 的提升轉換
-
整值轉換。如:template<unsigned int a> class A{}; A<3> m; 即從int 到unsigned int的轉換。
-
常規轉換
-
-
- 使用類模板時要注意其作用域,只能在其有效作用域內用它定義對象。
- 本文較大部分引用自https://blog.csdn.net/biu__biu_biu/article/details/78020620,十分感謝
-
-
- 模板有模板函數和模板類,定義方式如下: