Effective C++ 条款37 绝不重定义继承而来的缺省参数值
1. 重定义一个继承而来的non-virtual函数是应该避免的(见条款34,36),因此主要讨论为什么不重定义virtual函数的缺省参数值.
2. virtual函数的特点在于动态绑定,也就是运行时确定调用的函数实体,但令人惊讶的是,无论函数是否virtual,其缺省参数都是静态绑定的,例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Base{ public: void fun(int a=0){ ... } ... private: ... } class DerivedOne:public Base{ void fun(int a=1){ ... } private: ... }
那么如果通过B*类型的指针或引用调用fun而又不指定参数,a将会被附0!原因就在于C++对于缺省参数使用静态绑定策略.因为如果要实现对缺省参数的动态绑定,编译器就要在运行时确定缺省参数,这势必造成更慢更复杂的机制,"为了程序的执行速度和编译器在实现上的简易度,C++做了这样的取舍".
3. 要在派生类中为virtual函数设定与基类相同的缺省参数,可以使用条款35中列出的virtual函数的替代设计,其中之一就是NVI(non-virtual-interface)手法,即:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Base{ public: void wrapper(int a=0){ fun(a); } ... private: virtual fun(int a){ ... } ... } class Derived:public Base{ public: .... private: virtual fun(int a){ ... } }
由于不应该对non-virtual函数warpper函数进行重定义,因此wrapper函数传递给fun函数的缺省参数总是0,此外要改变整个继承体系的缺省参数也只需要改变Base成员wrapper的缺省参数即可.