绝不重新定义继承而来的缺省参数值
派生类在重写虚函数的时候,如果修改了缺省参数,实际运行的时候使用的还是基类的虚函数的缺省参数
class Shape {
public:
virtual void draw(int i = -1) const = 0;
};
class Rectangle : public Shape {
public:
virtual void draw(int i = 1) const {
cout << "Rectangle: " << i << endl;
}
};
class Circle : public Shape {
public:
virtual void draw(int i) const {
cout << "Circle: " << i << endl;
}
};
int main() {
Shape *pr = new Rectangle;
Shape *pc = new Circle;
pr->draw(3); // Rectangle: 3
pc->draw(4); // Circle: 4
pr->draw(); // Rectangle: -1 使用基类的缺省值
pc->draw(); // Circle: -1 使用基类的缺省值
Circle x;
x.draw(); // 静态绑定下,无法从base拿到默认值
return 0;
}
虚函数是动态绑定的,而缺省参数值是静态绑定
为了保持派生类和基类有相同的缺省参数,可以给派生类提供跟基类一样的缺省参数
class Shape {
public:
virtual void draw(int i = -1) const = 0;
};
class Rectangle : public Shape {
public:
virtual void draw(int i = -1) const {
cout << "Rectangle: " << i << endl;
}
};
这样感觉比较重复,而且如果基类的缺省参数改变,所有派生也都得改
解决办法是将draw
定义为非虚函数,然后调用一个私有的虚函数doDraw
,并传递参数,派生类重写doDraw
就行
class Shape {
public:
void draw(int i = -1) const {
doDraw(i); // 调用虚函数,并传递参数
}
private:
virtual void doDraw(int i) const = 0;
};
class Rectangle : public Shape {
private:
virtual void doDraw(int i) const {
cout << "Rectangle: " << i << endl;
}
};
class Circle : public Shape {
private:
virtual void doDraw(int i) const {
cout << "Circle: " << i << endl;
}
};
int main() {
Shape *pr = new Rectangle;
Shape *pc = new Circle;
pr->draw(3); // Rectangle: 3
pc->draw(4); // Circle: 4
pr->draw(); // Rectangle: -1
pc->draw(); // Circle: -1
Circle x;
x.draw(); // Circle: -1 这样就可以使用基类的默认值
return 0;
}