为了支持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。 只有涉及虚函数的地方才存在动态绑定!!!! 参考博客:https://blog.csdn.net/chgaowei/article/details/6427731