C++ — 静态绑定与动态绑定
2017-10-10 07:43
232 查看
静态绑定与动态绑定
——————————————————————————————————
静态绑定,动态绑定算是一个比较偏的知识点,这个也是我在Effective C++这本书当中学习到的. 我觉得很有必要写一篇博客记录.首先我们要知道静态类型和动态类型的概念:
静态类型:就是它在程序中被声明时所采用的类型(或理解为类型指针或引用的字面类型),在编译期确定;
动态类型:目前所指对象的类型。是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。
接下来我引用Effective C++这本书中的例子,帮助理解:
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; //请注意,以上这么写则当客户以对象调用此函数,一定要指定参数值. //因为静态绑定下这个函数并不从其base继承缺省参数值 //但若以指针(或reference)调用此函数,可以不指定参数值 //因为动态绑定下这个函数会从其base继承缺省参数值 ...... }; Shape *ps; // ps的静态类型为Shape*,它没有动态类型,因为它尚未指向任何对象; Shape *pc = new Circle; // pc的静态类型为Shape*,它的动态类型为Circle*; Shape *pr = new Rectangle; // pr的静态类型为Shape*,它的动态类型为Rectangle*; // 动态类型可以在程序执行过程中改变(通常是经由赋值动作): ps = pc; // ps的动态类型如今是Circle*; ps = pr; // ps的动态类型如今是Rectangle*;
现在我们来理解何为静态绑定和动态绑定???
静态绑定:又名前期绑定(eraly binding),绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译期;
动态绑定:又名后期绑定(late binding),绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行期;
比如常见的,virtual函数是动态绑定,non-virtual函数是静态绑定,缺省参数值也是静态绑定.Virtual函数系动态绑定而来,
意思是调用了一个virtual函数时,究竟调用那一份函数实现代码,取决于付出调用的那个对象的动态类型:
pc->draw(shape::Red); //调用Circle::draw(shape::Red) pr->draw(shape::Red); //调用Rectangle::draw(shape::Red)
其实这些都是老掉牙的知识点,但是今天我们带来了virtual函数不同的地方,缺省值! virtual函数是动态绑定的,而缺省参数
值为静态绑定. 意思是你可能会在"调用一个定义与derived class内的virtual函数"的同时,却使用base class为他所指定的缺省
参数值.
pr->draw(); //调用Rectangle::draw(shape::Red)!
此例当中,pr的动态类型为Rectangle*,所以调用的是Rectangle的virtual函数,一如你所预料.Rectangle::draw函数的缺省值应
该是Green,但由于pr的静态类型为shape*,所以此一调用的缺省参数值来自shape class而非Rectangle class!结局是这个函数调
用有这奇怪并且几乎没有人预料得到的组合,由shape class和Rectangle class的draw生命式各处一份力.以上事实不只局限于
"ps,pc和pr都是指针"的情况;即使把指针换成references问题依然存在.重点在于draw是一个virtual函数,而它有个缺省参数值在
derived class中被重新定义了.
为什么C++坚持以这种乖张的方式来运作呢? 答案在于运行期效率. 如果缺省参数值为动态绑定,编译器就必须有某种方法在运行
期为virtual函数决定适当的参数缺省值.这比目前实行的"在编译器决定"的机制更慢而且更复杂.为了程序的执行速度和编译器实
现上的简易度,C++做了这样的取舍,其结果就是你如今所享受的执行效率. 但是如果你重新定义了继承而来的缺省参数值,而且偏
偏在缺省参数值上面出现bug,那么你可能需要一个通宵都不一定调的出来.
相关文章推荐
- 深入理解C++的动态绑定和静态绑定
- 关于静态绑定与动态绑定的辨别笔记----C++学习之路
- C++动态绑定与静态绑定
- C++的静态绑定(称静态联编或者早绑定)和动态绑定(动态联编或者晚捆绑) 类继承virtural中用的
- 深入理解C++的动态绑定和静态绑定
- 深入理解C++的动态绑定和静态绑定
- 深入理解C++的动态绑定和静态绑定
- 深入理解C++的动态绑定和静态绑定
- 深入理解C++的动态绑定和静态绑定
- 深入理解C++的动态绑定和静态绑定
- 【转】C++动态绑定,静态绑定,虚函数
- c++动态绑定、静态绑定与java中动态绑定与静态绑定的比较
- 深入理解C++的动态绑定和静态绑定--一个牛人写的文章,浅显易懂
- 深入理解C++的动态绑定与静态绑定的应用详解
- 深入理解C++的动态绑定和静态绑定
- c++动态绑定和静态绑定
- 深入理解C++的动态绑定和静态绑定
- 深入理解C++动态绑定和静态绑定
- C++的动态绑定和静态绑定
- 深入理解C++的动态绑定和静态绑定