深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"

深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值"

看条款38 的时候不是很理解, 于是写了个测试代码

#include < iostream >  
using   namespace  std; 

class  A{
public :
    
virtual   void  show( int  a = 145 )
    {
        cout
<< " A: a= " << a << endl; 
    }   
}; 

class  B:  public  A 

public
    
void  show( int  b)
    { 
        cout
<< " B: b= " << b << endl; 
    } 
}; 
class  C:  public  B 

public
    
void  show( int  c = 999 )
    { 
        cout
<< " C: c= " << c << endl; 
    } 
};
class  D:  public  C 

public
    
void  show()
    { 
        cout
<< " D:\n "
    }
}; 

void  main() 
{
    A 
* pp;
    A a; 
    B b; 
    C c; 
    D d;
    
    a.show();
    pp 
=   & a;    pp -> show();

    
//  b.show();   //  error C2660: 'B::show' : function does not take 0 arguments
    pp  =   & b;    pp -> show();
    
    c.show();
    pp 
=   & c;    pp -> show();

    d.show();
    pp 
=   & d;    pp -> show();
    
    C 
* pc =   & d;
    pc
-> show();

    system(
" pause " ); 
}   
输出结果是
A: a=145
A: a=145
B: b=145
C: c=999
C: c=145
D:
C: c=145
C: c=999

回顾条款 
虚函数是动态绑定而缺省参数值是静态绑定的.  为什么C++坚持这种有违常规的做法呢?答案和运行效率有关。如果缺省参数值被动态绑定,编译器就必须想办法为虚函数在运行时确定合适的缺省值,这将比现在采用的在编译阶段确定缺省值的机制更慢更复杂。做出这种选择是想求得速度上的提高和实现上的简便,所以大家现在才能感受得到程序运行的高效;

所以
a. 静态绑定 .vs. 动态绑定
A *pp  =  new B;
这里 pp 静态绑定是 A* , 而动态绑定却是 B*
B *pb = new B;
这里 pb 静态绑定和动态绑定是一样的都是 B*

b. 缺省值是静态绑定的, 而非动态绑定
所以
d.show() 输出 D:  因为show 被 D override

pp  =   & d;    pp -> show();  
pp 被动态绑定到D *, 但是show 的缺省值却是A* 的 145, 所以输出的是 C: c=145, 而不是999 ( 函数 show 被C 给override 了) 

而 C *pc = &d; pc->show() , pc 静态绑定为C*, 而动态绑定为 D* , 所以输出的是 C: c=999 , 999 是 C* 静态绑定的缺省值

c. 所以调用b.show 的时候出现了如下的错误
     //  b.show();   //  error C2660: 'B::show' : function does not take 0 arguments
因为 B* 没有静态绑定的函数

结论就是 决不要重新定义继承而来的缺省参数值 

ref: 
从这里学了不少:)  http://bbs.chinaunix.net/viewthread.php?tid=439188 

你可能感兴趣的:(深入理解Effictive C++ "条款38: 决不要重新定义继承而来的缺省参数值")