首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C++ 實用技巧:預設參數在函數指標、成員指標與 typedef 中的陷阱

     編輯:VC 教學

標準規定 vs 編譯器擴充

C++ 標準禁止在下列宣告中出現預設參數:

  • 函數指標型別:void (*pf)(int = 120);
  • 成員函數指標:void (A::*pmf)(int = 50);
  • typedef 函數型別:typedef void (*PF)(int = 100);
  • 函數參考 typedef:typedef void (&PRF)(int = 100);

但許多編譯器(MSVC、GCC 等)作為非標準擴充予以接受,導致可攜性風險。

實際行為差異

struct A { void func(int x=5) {} };
void g(int n=12) {}

void (*pf)(int = 120);
void (A::*pmf)(int = 50);
typedef void (*PF)(int = 100);
typedef void (&PRF)(int = 100);

int main() {
    pf = g;
    PF pf2 = g;
    pmf = &A::func;
    A a;
    pf();   // 呼叫 g,參數用 120(pf 的預設值)
    pf2();  // 呼叫 g,參數用 100(PF 的預設值)
    (a.*pmf)(); // 呼叫 A::func,參數用 50(pmf 的預設值)
}

同一函數透過不同指標/型別呼叫時,使用的預設值取決於指標/型別宣告處的預設值,而非函數原始定義。這極易造成維護混淆。

最佳實務

  1. 完全避免在函數指標、成員指標、typedef 中寫預設參數。
  2. 若既有程式碼已使用,務必加上註解標註預期預設值來源。
  3. 升級編譯器時測試相關呼叫點,確保行為一致。
  4. 合法場景(函數本身宣告)建議在呼叫端以註解說明使用的預設值。

標準演進提醒

C++11/14/17/20 均未放寬此限制。未來版本可能直接報錯,建議盡早清理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved