author:
- luixiao1223
title: never redefine default parameter value
我们已经说过重新改写继承而来的非虚函数是不允许的。那么我们局限于讨论继承而来带有默认参数的虚函数。
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;
};
看起来没问题的代码,可能会出问题。比如
Shape* pc;
Shape* pc=new Circle;
Shape* pr=new Rectangle;
pr->draw(); //默认参数是Red不是Green.
这个结果的原因是很有趣的,函数参数的绑定是静态行为不是动态行为。所以默认参数来自于Shape,因为指针是一个静态类型,而他指向的对象的动态类型是Rectangle。如果你用引用这些问题仍然存在。
之所以函数的默认参数是静态绑定,是为了效率。编译器不考虑过于复杂的动态默认参数行为。