Effective C++ 条款37 绝不重定义继承而来的缺省参数值

1. 重定义一个继承而来的non-virtual函数是应该避免的(见条款34,36),因此主要讨论为什么不重定义virtual函数的缺省参数值.

2. virtual函数的特点在于动态绑定,也就是运行时确定调用的函数实体,但令人惊讶的是,无论函数是否virtual,其缺省参数都是静态绑定的,例如:

class Base{
public:
    void fun(int a=0){
       ...
    }
    ...
private:
    ...
}
class DerivedOne:public Base{
    void fun(int a=1){
        ...
    }
private:
    ...
}
View Code

那么如果通过B*类型的指针或引用调用fun而又不指定参数,a将会被附0!原因就在于C++对于缺省参数使用静态绑定策略.因为如果要实现对缺省参数的动态绑定,编译器就要在运行时确定缺省参数,这势必造成更慢更复杂的机制,"为了程序的执行速度和编译器在实现上的简易度,C++做了这样的取舍".

3. 要在派生类中为virtual函数设定与基类相同的缺省参数,可以使用条款35中列出的virtual函数的替代设计,其中之一就是NVI(non-virtual-interface)手法,即:

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){
    ...
    }
}
View Code

由于不应该对non-virtual函数warpper函数进行重定义,因此wrapper函数传递给fun函数的缺省参数总是0,此外要改变整个继承体系的缺省参数也只需要改变Base成员wrapper的缺省参数即可.

原文地址:https://www.cnblogs.com/reasno/p/4799122.html