c++多態

C++中的多態(雖然多態不是C++所特有的,可是C++中的多態確實是很特殊的)分爲靜多態和動多態(也就是靜態綁定和動態綁定兩種現象),靜動的區別主要在於這種綁定發生在編譯期仍是運行期,發生在編譯期的是靜態綁定,也就是靜多態;發生在運行期的則是動態綁定,也就是動多態。

靜多態能夠經過模板和函數重載來實現(之所說C++中的多態主要仍是由於模板這個東西),下面舉兩個例子:
1)函數模板
template <typename T>
T max(const T& lsh, const T& rhs) 
{
    return (lsh > rhs) ? lsh : rhs;
}
回兩個任意類型對象的最大值(對象),前提是該類型可以使用>運算符進行比較,而且返回值是bool類型。
使用:
int a = 3;
int b = 4;
cout << max(a, b) << endl;
float c = 2.4;
float d = 1.2;
cout << max(c, d) << endl;
輸出結果爲:
         4
2.4
這種綁定發生在編譯期,這是因爲模板的實例化是發生在編譯期的,即在編譯時編譯器發現你調用max(a, b)時就自動生成一個函數
int max(const int& lsh, const int& rhs) 
{
      return (lsh > rhs) ? lsh : rhs;
}
即將全部的T替換成int;
當你調用max(c, d)時就自動生成一個函數
float max(const float& lsh, const float& rhs)
{
    return (lsh > rhs) ? lsh : rhs;
}
 

 

之因此說開始的函數定義是函數模板,就是由於他就像個模子似的,你能夠用鋁做爲原料也能夠用石膏或者銅。
2)函數重載:
int max (int a, int b)
{
      return (a > b) ? a : b;
}
int max (int a, int b, int c)
{
     return max(max(a, b), c);
}
兩個函數名稱同樣,參數類型或個數不徹底相同,返回值同樣(這個不重要)。
使用:
int a = 3, b = 4, c = 5;
cout << max(a, b) << endl;
cout << max(a, b, c) << endl;
 
輸出結果爲:
4
5
肯定函數的過程也發生在編譯器,當你使用max(a, b),編譯器發現只有兩個參數,那麼就調用只有兩個參數的函數版本,當使用max(a, b, c)時,編譯器則使用有3個參數的版本。
經過上面的兩個例子,你還可使用更爲方便的模板函數重載:
template <typename T>
T max(const T& lsh, const T& rhs) 
{
       return (lsh > rhs) ? lsh : rhs;
}
 
template <typename T>
T max(const T& a, const T& b, const T& c)
{
      return max(max(a, b), c);
}
int main()
{
  float a = 3.6, b = 1.2, c = 7.8;
  cout << max(a, b, c) << endl;
return 0;
}
 

 

 
輸出:
7.8
經過參數個數和類型,編譯器自動生成和調用對應得函數版本!

動多態則是經過繼承、虛函數(virtual)、指針來實現。
class A {
public:
    virtual void func() const {
         coust << 「A::func()」 << endl;
    }
}
class B : public A {
public: 
   virtual void func() const {
        coust << 「B::func()」 << endl;
   }
}
int main()
{
  A* a = B();

  a->func();
  return 0; }
輸出:
     B::func()
編譯期是不調用任何函數的,編譯器編譯到a->func()時只是檢查有沒有語法問題,通過檢查沒有。編譯器並不知道調用的是A版本的func()仍是B版本的func(),因爲a是一個指向B對象的指針,因此a只知道它指向的是一個A類型(或者能轉換成A類型)的對象。一般集成體系就說明了(因爲是公有繼承)B是一種A。在運行期,a要調用a所指向對象的func()函數,就對它指向的對象下達調用func()的命令,結果a所指向的是一個B對象,這個對象就調用了本身版本(B版)的func()函數,因此輸出時B::func()

總結:
在編譯期決定你應該調用哪一個函數的行爲是靜態綁定(static-binding),這種現象就是靜多態。
在運行期決定應該調用哪中類型對象的函數的行爲是動態綁定(dynamic-binding),這種現象就是動多態。
相關文章
相關標籤/搜索