回覆列表
  • 1 # Vcddh

    C++中的多型(雖然多型不是C++所特有的,但是C++中的多型確實是很特殊的)分為靜多型和動多型(也就是靜態繫結和動態繫結兩種現象),靜動的區別主要在於這種繫結發生在編譯期還是執行期,發生在編譯期的是靜態繫結,也就是靜多型;發生在執行期的則是動態繫結,也就是動多型。

    靜多型可以透過模板和函式過載來實現(之所說C++中的多型主要還是因為模板這個東西),下面舉兩個例子:

    1)函式模板

    template<typenameT>

    Tmax(constT&lsh,constT&rhs)

    {

    return(lsh>rhs)?lsh:rhs;

    }

    返回兩個任意型別物件的最大值(物件),前提是該型別能夠使用>運算子進行比較,並且返回值是bool型別。

    使用:

    inta=3;intb=4;

    cout<<max(a,b)<<endl;

    floatc=2.4;floatd=1.2;

    cout<<max(c,d)<<endl;

    輸出結果為:

    4

    2.4

    這種繫結發生在編譯期,這是由於模板的例項化是發生在編譯期的,即在編譯時編譯器發現你呼叫max(a,b)時就自動生成一個函式

    intmax(constint&lsh,constint&rhs)

    {

    return(lsh>rhs)?lsh:rhs;

    }

    即將所有的T替換成int;

    當你呼叫max(c,d)時就自動生成一個函式

    floatmax(constfloat&lsh,constfloat&rhs)

    {

    return(lsh>rhs)?lsh:rhs;

    }

    之所以說開始的函式定義是函式模板,就是因為他就像個模子似的,你可以用鋁作為原料也可以用石膏或者銅。

    2)函式過載:

    intmax(inta,intb)

    {

    return(a>b)?a:b;

    }

    intmax(inta,intb,intc)

    {

    returnmax(max(a,b),c);

    }

    兩個函式名稱一樣,引數型別或個數不完全相同,返回值一樣(這個不重要)。

    使用:

    inta=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<typenameT>

    Tmax(constT&lsh,constT&rhs)

    {

    return(lsh>rhs)?lsh:rhs;

    }

    template<typenameT>

    Tmax(constT&a,constT&b,constT&c)

    {

    returnmax(max(a,b),c);

    }

    使用

    floata=3.6,b=1.2,c=7.8;

    cout<<max(a,b,c)<<endl;

    輸出:

    7.8

    透過引數個數和型別,編譯器自動生成和呼叫對應得函式版本!

    動多型則是透過繼承、虛擬函式(virtual)、指標來實現。

    classA{

    public:

    virtualvoidfunc()const{

    coust<<“A::func()”<<endl;

    }

    }

    classB:publicA{

    public:

    virtualvoidfunc()const{

    coust<<“B::func()”<<endl;

    }

    }

    使用:

    Aa*=B();

    a->func();

    輸出:

    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),這種現象就是動多型

  • 中秋節和大豐收的關聯?
  • 有沒有好喝的白酒牌子推薦,謝謝大家~?