动态绑定与静态绑定
静态类型,就是它在程序中被声明时所采用的类型,在编译期确定,不可更改。
动态类型,则是“目前所指的对象的类型”,在运行期决定的,可以更改。
静态绑定,绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
动态绑定,绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。
静态多态性与动态多态性
静态多态性:
- 函数多态性——函数重载
- 模板多态性——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;
……
};