本文环境: a.FreeBSD gcc version 4.2.1 20070719
首先,对于函数默认参数,无论是普通成员还是类成员的默认值,大家都知道,是静态绑定的;今天通过以下的例子来观察观察默认参数
1. 函数前置声明的默认参数
extern void Display(int i=100);
int main() {...}
void Display(int i=200) {}
错误 ,error : default argument given for parameter1 of "void Display(int) after previous specification in void Display(int)"
2. 函数前置声明的另一种形式
int main() {extern void Display(int i=100); Display(); ...}
void Display(int i=500) {...}
这里可以编译的过,以声明的默认参数为主
3. class IBase{public: virtual void Display(int i=100);} //子类于基类默认参数不一致
class CBase{public: virtual void Display(int i=200);}
用基类调用就用基类的默认参数,用子类调用就用子类的默认参数
CBase* pBase = new CBase; pBase->Display()/*200*/;
IBase* pTemp = pBase; pTemp->Display();/*100*/
4. 对于模板函数来说,template<class T1, class T2 /*= float*/> //函数摸板参数是不可以默认的,
你换这样也不行template<class T1, int size=10>
5. template<class T1, class T2>
void Display(T1 a, T2 b = T2(10));
int main() {Display<float, int>(3.8);} //调用声明的默认值(10)
template<class T1, class T2>
void Display(T1 a, T2 b=T2(100)) {...}
模板函数不能在调用里声明
6. template<class T1, class T2=float> //这个
class CTempBase
{
void TempClassDisplay(T1 a, T2=T2(10.3)) {...}
};
int main() {CTempBase<int> objBase; objBase.TempClassDisplay(); 没问题,默认参数是10.3
7. 6还可以这样 template<class T1, class T2=float> class CTempBase2; 声明
template<class T1, class T2> //定义
class CTempBase2
{
void TempClassDisplay2(T1 a, T2 b=T2(2.7));
};
int main()
{
CTempBase2<int> objBase; objBase.TempClassDisplay(20); //没问题,默认参数是2.7
}
8.继承关系的模板类默认参数和模板类函数默认参数
template<class T1, class T2=float, class T3=int>
class ITempBase3
{
virtual void Test(T1 a, T2 b, T3 c=T3(2)) = 0;
}
template<class T1, class T2=int, class T3=float>
class CTempBase3: public ITempBase3<T1, T2, T3> //对类来说,模板参数不同就是不同的类了,所以具体类的参数决定了是基类的参数
{
virtual void Test(T1 a, T2 b, T3 c=T3(200)) {......} //函数还是和3一样,那个类调用的,就用哪个类的默认参数
}
总结一下,默认参数是静态绑定的,根据上下文在编译的时候就已经决定了的
void Display(int m = 300);
Display();
00412223 push 12Ch //这个常值编译中就已经产生了,就是高级语言---汇编语言那步.由编译器产生的,
00412228 call Display (4112EEh)
0041222D add esp,4
我们在编程的时候,尽量在头文件里声明函数,声明于定义的默认参数最好要保持一致,以免造成一些误会。
如果第三方库的默认参数不是很符合你的胃口,可以自己包个函数间接调用第三方库的函数,然后,默认参数你爱用啥用啥吧
实在想不出有啥理由需要函数声明默认参数于实际参数不一致的