C++的静态绑定(称静态联编或者早绑定)和动态绑定(动态联编或者晚捆绑) 类继承virtural中用的
2013-08-17 17:34
295 查看
C++为了支持多态性,才用了动态绑定和静态绑定。
首先理解四个名词:
1.对象的静态类型:对象在声明时采用的类型,是在编译期确定的。
2.对象的动态类型:目前所指对象的类型,是在运行期决定的。
4.动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。
这边我们看一下,pD->DoSomething()和pB->DoSomething()调用的是同一个函数吗?这边显然指的不是同一个对象,因为DoSomething是一个no-virtual函数,它是金泰绑定的,也就是编译器会在编译期根据对象的静态类型来选择函数。所以pD->DoSomething()就等同于D::DoSomething,pB->DoSomething()就等同于B::DoSomething()。
再看下pD->vfun()和pB->vfun()调用的是同一个函数吗?这边就是了,因为vfun是一个virtual函数,它是动态绑定的,也就是说它绑定的是对象的动态类型,pB和pD虽然静态类型不同,但是当它们指向同一个对象的时候,他们的动态类型是相同的,都是D*,所以两者指向的都是同一个函数:D::vfun()。
以上介绍的是指针,对于引用(reference)的情况同样适用。
下面我们再介绍一种特殊情况:
virtual函数是动态绑定的,而缺省参数却是静态绑定的。
带有参数的是动态绑定,缺省参数的是静态绑定。意思是你可能在调用“一个定义于derived class内的virtual函数”的同时,却使用base class为他所指定的缺省参数值:
pr的动态类型是Rectangle*,所以调用的是Rectangle的virtual函数,Rectangle::draw函数的缺省参数应该是Green,但是pr的静态类型是Shape*,所以调用缺省参数值来自Shape class而非来自Rectangle class。
为什么C++坚持这种方式来运作呢?答案在于长期效率。如果缺省参数是动态绑定的,编译器就必须有某种办法在运行为virtual函数决定适当的参数缺省值。这个比较复杂,为了程序执行的速度和编译速度,这样取舍,保证效率
首先理解四个名词:
1.对象的静态类型:对象在声明时采用的类型,是在编译期确定的。
2.对象的动态类型:目前所指对象的类型,是在运行期决定的。
class B {}; class C:public B {}; class D:public B {}; D* pD=new D();//pD的静态类型是D*,动态类型也是D* B* pB=pD; //PB的静态类型是B*,动态类型是D* C* pC=new C(); pB=pC; //pB的动态类型改变了,现在变成了C* ,所以从这可看出,动态类型是可以改变的,静态类型是不可以改变的(废话,声明时候所表示的还能改变吗?)3.静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
4.动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。
静态联编说的是在编译时就已经确定好了调用和被调用两者的关系 动态联编说的是程序在运行时才确定调用和被调用者的关系.
动态联编必须包括以下方面: 成员函数必须申明为virtual 如果基类中申明了为虚函数,则派生类中不必再申明。 调用方式: 通过对象的指针或引用调用成员函数;或通过成员函数调用
class B { public: void DoSomething(); virtual void vfun(); }; class C:public B { public: void DoSomething(); virtual void vfun(); }; class D:public B { public: void DoSomething(); virtual void vfun(); }; D* pD=new D(); B* pB=pD;
这边我们看一下,pD->DoSomething()和pB->DoSomething()调用的是同一个函数吗?这边显然指的不是同一个对象,因为DoSomething是一个no-virtual函数,它是金泰绑定的,也就是编译器会在编译期根据对象的静态类型来选择函数。所以pD->DoSomething()就等同于D::DoSomething,pB->DoSomething()就等同于B::DoSomething()。
再看下pD->vfun()和pB->vfun()调用的是同一个函数吗?这边就是了,因为vfun是一个virtual函数,它是动态绑定的,也就是说它绑定的是对象的动态类型,pB和pD虽然静态类型不同,但是当它们指向同一个对象的时候,他们的动态类型是相同的,都是D*,所以两者指向的都是同一个函数:D::vfun()。
以上介绍的是指针,对于引用(reference)的情况同样适用。
下面我们再介绍一种特殊情况:
virtual函数是动态绑定的,而缺省参数却是静态绑定的。
class Shape{ public: enum ShapeColor {Red,Green,Blue}; virtual void draw(ShapeColor color=Red) const=0; }; class Rectangle:public Shape{ public: virtual void draw(ShapeColor color=Green) const; }; class Circle:public Shape{ public: virtual void draw(ShapeColor color) const; }; //不管ps,pc,pr指向哪儿,静态类型都是Shape* Shape *ps; Shape *pc=new Circle(); Shape *pr=new Rectangle(); ps=pr; ps=pc; pc->draw(Shape::Red); //调用Circle::draw pr->draw(Shape::Red); //调用Rectangle::draw pr->draw(); //调用Rectangle::draw,使用Shape::draw里面的参数值
带有参数的是动态绑定,缺省参数的是静态绑定。意思是你可能在调用“一个定义于derived class内的virtual函数”的同时,却使用base class为他所指定的缺省参数值:
pr的动态类型是Rectangle*,所以调用的是Rectangle的virtual函数,Rectangle::draw函数的缺省参数应该是Green,但是pr的静态类型是Shape*,所以调用缺省参数值来自Shape class而非来自Rectangle class。
为什么C++坚持这种方式来运作呢?答案在于长期效率。如果缺省参数是动态绑定的,编译器就必须有某种办法在运行为virtual函数决定适当的参数缺省值。这个比较复杂,为了程序执行的速度和编译速度,这样取舍,保证效率
相关文章推荐
- [effectiv c++]条款37:绝不重新定义继承而来的缺省参数值(动态绑定,静态绑定,多态性)
- 深入理解C++的动态绑定和静态绑定
- C++动态绑定与静态绑定
- C++中的动态绑定与静态绑定
- 利用C++模板,代替虚函数实现类的静态多态性及动态继承
- c++的动态绑定和静态绑定
- C++的静态绑定与动态绑定
- 深入理解C++的动态绑定和静态绑定
- 深入理解C++的动态绑定和静态绑定
- C++ 静态绑定和动态绑定
- 深入理解C++的动态绑定和静态绑定
- 【转】深入理解C++的动态绑定和静态绑定 & 不要重定义虚函数中的默认参数
- c++动态绑定和静态绑定
- 深入理解C++的动态绑定与静态绑定的应用详解
- 深入理解C++的动态绑定和静态绑定
- Java继承机制的初始化顺序+静态动态绑定
- c++ 多重继承中的动态绑定
- C++ — 静态绑定与动态绑定
- 深入理解C++的动态绑定和静态绑定
- 深入理解C++的动态绑定与静态绑定的应用详解