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

动态绑定与静态绑定

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

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

静态多态性与动态多态性

静态多态性:

  • 函数多态性——函数重载
  • 模板多态性——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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值