[effectiv c++]条款37:绝不重新定义继承而来的缺省参数值(动态绑定,静态绑定,多态性)

来源:互联网 发布:java面对对象 编辑:程序博客网 时间:2024/05/18 18:53

动态绑定与静态绑定

静态类型,就是它在程序中被声明时所采用的类型,在编译期确定,不可更改。
动态类型,则是“目前所指的对象的类型”,在运行期决定的,可以更改。

静态绑定,绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
动态绑定,绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。

静态多态性与动态多态性

静态多态性:

  • 函数多态性——函数重载
  • 模板多态性——C++模板(类模板、函数模板)

动态多态性:

  • 虚函数

静态多态性与动态动态性的比较:http://www.cnblogs.com/Leo_wl/p/3667870.html

举例

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;    ……};void Test() {    Shape *ps;                  // 静态类型为 Shape*    Shape *pc = new Cirle;      // 静态类型为 Shape*,动态类型为 Cirle*    Shape *pr = new Rectangle;  // 静态类型为 Shape*, 动态类型为 Rectangle*    pr->draw();                 // 调用 Rectangle::draw(Shape::Red)                                // 而不是 Rectangle::draw(Shape::Green)}

virtual函数系动态绑定而来,所以在调用一个virtual函数时,究竟调用哪一份函数实现代码,取决于发出调用的那个对象的动态类型。
而缺省参数却是静态绑定,取决于发出调用的对象的静态类型。

如果想要pr->draw();调用Rectangle::draw(Shape::Green) 该怎么办?

可以采用NVI(non-virtual interface)手法替代virtual函数。

NVI手法:令base class内的一个public non-virtual函数调用private virtual函数,后者可被derived class重新定义。

这里我们可以让non-virtual函数指定缺省参数,而private virtual函数负责真正的工作。

class Shape {public:    enum ShapeColor { Red, Green, Blue };    void draw(ShapeColor color = Red) const  //non-virtual    {        doDraw(color);  //调用一个virtual    }    …………private:    virtual void doDraw(ShapeColor color) const = 0; // 负责真正的工作};class Rectangle: public Shape {public:    ……private:    virtual void doDraw(ShapeColor color) const;    ……};
阅读全文
0 0
原创粉丝点击