本文环境: 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

我们在编程的时候,尽量在头文件里声明函数,声明于定义的默认参数最好要保持一致,以免造成一些误会。

如果第三方库的默认参数不是很符合你的胃口,可以自己包个函数间接调用第三方库的函数,然后,默认参数你爱用啥用啥吧

实在想不出有啥理由需要函数声明默认参数于实际参数不一致的