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

本文讨论了在继承虚拟函数时遇到的默认参数冲突问题,并提出了使用non-virtualinterface手法来解决此问题的方法。重点阐述了如何避免在继承过程中设置默认参数值,以及在基类与派生类中实现相同静态对象初始值的正确做法。

在继承一个virtual函数的时候,如果这个virtual函数同样是有默认值的话,那么其表明这次继承既存在动态绑定也存在静态绑定:例如下面这个例子:

 1 class Shape{
 2 public:
 3     enum shapeColor{red, green, blue};
 4     virtual void draw(shapeColor color = red)const = 0;
 5     //注意,这里的颜色是静态绑定的
 6 };
 7 class Recantagle : public Shape{
 8 public:
 9     void draw(shapeColor color = green)const;
10     //但是这里的默认参数!!!
11 };
12 class Circle : public Shape{
13 public:
14     void draw(shapeColor color) const;
15 };
这里就出现问题了,当使用一个Shape指针调用虚函数draw的时候,像下面这样:
Shape * sp = new Revantagle();  
sp->draw();
对于这个draw函数来说,结果害死没问题的,起执行的肯定还是动态绑定,但是对于draw的默认参数就会有问题了,其执行的将会是基类中的参数red,因为对于他只能执行静态绑定。
即使在base class与derived class中提供相同的静态对象的默认初始值,那么情况也不好,这样造成的是base class 与derived class的代码相互依赖
 
 
解决这个的一般办法是:使用所谓的non-virtual interface手法:
 1 class Shape{
 2 public:
 3     enum shapeColor{red, green, blue};
 4     void draw(shapeColor & color = red) const {
 5         doDraw(color);
 6     }
 7 private://注意这里是private
 8     virtual void doDraw(shapeColor & )const = 0;
 9 };
10 class Recantagle : public Shape{
11 public:
12     //直接继承基类的public函数即可
13 private:
14     void doDraw(shapeColor & ) const;
15 };
这样的就实现了同上面一样的效果。
 
小结:绝对不要去定义一个继承而来的缺省的参数值,即使继承到的是相同的参数值也不可行,virtual函数确是唯一应该被复写的东西

转载于:https://www.cnblogs.com/-wang-cheng/p/4889786.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值