看条款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