您的位置:首页 > 其它

条款37:绝不重新定义继承而来的缺省参数

2015-05-24 12:02 274 查看
在继承中,分为两类函数:virtual和non-virtual。而重新定义一个非虚函数是不好的(条款36),那么以下的讨论就是如何定义继承而来的虚函数。

强调:虚函数是动态绑定的,而缺省参数值是静态绑定的。

#include <iostream>

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;  // 混淆设计:重新定义了继承而来的缺省参数值
};
void Rectangle::draw(ShapeColor color) const
{
std::cout << color << std::endl;
}

class Circle : public Shape
{
public:
virtual void draw(ShapeColor color) const;  //
};
void Circle::draw(ShapeColor color) const
{
std::cout << color << std::endl;
}

int main()
{
Shape* ps;                             // 静态类型为Shape*
Shape* pr = new Rectangle;         // 静态类型为Shape*
Shape* pc = new Circle;              // 静态类型为Shape*

pr->draw();                            // 相当于调用了Rectangle::draw(Shape::Red)
pr->draw(Rectangle::Green);            // 调用Rectangle::draw(Rectangle::Green)
pc->draw(Circle::Blue);                // 调用Circle::draw(Circle::Blue)

return 0;
}


说明:

关于类型:ps、pr、pc不论其指向什么,静态类型都为Shape*。所谓动态类型,就是当前所指对象的类型,如,pr的动态类型是Rectangle*,pc的动态类型是Circle*,ps未指向任何对象,因此没有动态类型。

关于重定义缺省值:如上例中的pr->draw(),我们的本意可能是调用Rectangle::draw(Rectangle::Green),可实际上调用的是Rectangle::draw(Shape::Red),结果就是:调用的是派生类的函数,而使用的却是基类的默认参数,真是不伦不类。导致这种结果的原因就是:缺省参数值是静态绑定的,其总是根据pr的静态类型去寻找默认参数值,我们必须避免这种糟糕的设计。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐