码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-05-24 12:54:55      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:

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

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

 1 #include <iostream>
 2 
 3 class Shape
 4 {
 5 public:
 6     enum ShapeColor{ Red, Green, Blue };
 7     virtual void draw(ShapeColor color = Red) const = 0;
 8 };
 9 
10 class Rectangle : public Shape
11 {
12 public:
13     virtual void draw(ShapeColor color = Green) const;  // 混淆设计:重新定义了继承而来的缺省参数值
14 };
15 void Rectangle::draw(ShapeColor color) const
16 {
17     std::cout << color << std::endl;
18 }
19 
20 class Circle : public Shape
21 {
22 public:
23     virtual void draw(ShapeColor color) const;  //
24 };
25 void Circle::draw(ShapeColor color) const
26 {
27     std::cout << color << std::endl;
28 }
29 
30 int main()
31 {
32     Shape* ps;                             // 静态类型为Shape*
33     Shape* pr = new Rectangle;         // 静态类型为Shape*
34     Shape* pc = new Circle;              // 静态类型为Shape*
35 
36     pr->draw();                            // 相当于调用了Rectangle::draw(Shape::Red)
37     pr->draw(Rectangle::Green);            // 调用Rectangle::draw(Rectangle::Green)
38     pc->draw(Circle::Blue);                // 调用Circle::draw(Circle::Blue)
39 
40     return 0;
41 }
42         

说明:

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

关于重定义缺省值:如上例中的pr->draw(),我们的本意可能是调用Rectangle::draw(Rectangle::Green),可实际上调用的是Rectangle::draw(Shape::Red),结果就是:调用的是派生类的函数,而使用的却是基类的默认参数,真是不伦不类。导致这种结果的原因就是:缺省参数值是静态绑定的,其总是根据pr的静态类型去寻找默认参数值,我们必须避免这种糟糕的设计。

 

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

标签:

原文地址:http://www.cnblogs.com/benxintuzi/p/4525620.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!