標籤:虛函數 無法 str something color eth 支援 return 關於
為了支援c++的多態性,才用了動態綁定和靜態繫結。
1、對象的靜態類型:對象在聲明時採用的類型。是在編譯期確定的。
2、對象的動態類型:目前所指對象的聲明。在運行期決定。對象的動態類型可以更改,但是靜態類型無法更改。
關於對象的靜態類型和動態類型,看一個樣本:
class A{};class B: public A{};class C: public A{};int main(){ C *pc=new C();//pc的靜態類型是它聲明的類型C*,動態類型也是C* A *pa=pc;//pa的靜態類型是它聲明的類型A*,pa的動態類型所指向的對象pc的類型A* B *pb=new B(); pa=pb;//pa的動態類型是可以更改的,現在它的動態類型是B* return 0;}
3、靜態繫結:綁定的是對象的靜態類型,某特性(比如函數)依賴於對象的靜態類型,發生在編譯期。
4、動態綁定:綁定的是對象的動態類型,某特性(比如函數)依賴於對象的動態類型,發生在運行期。
class A{public: void dosomething() { cout<<"A"<<endl; } virtual void fun() { cout<<"virtual A"<<endl; }};class B: public A{public: void dosomething() { cout<<"B"<<endl; } virtual void fun() { cout<<"virtual B"<<endl; }};class C: public A{public: void dosomething() { cout<<"C"<<endl; } virtual void fun() { cout<<"virtual C"<<endl; }};int main(){ C *pc=new C();//pc的靜態類型是它聲明的類型C*,動態類型也是C* pc->dosomething(); // C pc->fun(); // virtual C A *pa=pc;//pa的靜態類型是它聲明的類型A*,pa的動態類型所指向的對象pc的類型A* pa->dosomething(); // A ① pa->fun(); // virtual C B *pb=new B(); pb->dosomething(); //B pb->fun(); // virtual B pa=pb;//pa的動態類型是可以更改的,現在它的動態類型是B* pa->dosomething(); // A ② pa->fun(); // virtual B return 0;}
dosomething()是一個非虛函數,它是靜態繫結的,也就是在編譯的時候根據對象的靜態類型來選擇函數,所以,pa、pb、pc調用的都是自己的的dosomething()函數,但對於①中的pa的fun()函數和②中的pa的fun()函數,因為fun()為虛函數,它們綁定的是動態對象,所以①的pa調用的是pc的fun()函數,②的pa調用的是pb的fun()函數。
需要注意的是:
當預設參數和虛函數一起出現的時候情況就有點複雜,因為虛函數是動態綁定的,但是為了執行效率,預設參數是靜態繫結的。
class A{public: virtual void fun(int i=10) { cout<<"virtual A "<<i<<endl; }};class B: public A{public: virtual void fun(int i=20) { cout<<"virtual B "<<i<<endl; }};int main(){ B *b=new B(); A *a=b; b->fun();//virtual B 20 a->fun();//virtual B 10 return 0;}
b->fun()、a->fun()調用的都是b的fun()函數,但是預設函數是靜態繫結的,所以a->fun()調用的是a的虛函數fun()裡面的預設值10,b->fun()調用的是b的虛函數fun()裡面的預設值20。
只有涉及虛函數的地方才存在動態綁定!!!!
參考部落格:6427731
c++的動態綁定和靜態繫結