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

C++ 跨平台開發實戰 (二):語法層面移植性陷阱大全

     編輯:關於C++

舊式編譯器相容性策略

針對不完全支援 C++98 的舊編譯器 (如 VC6),透過避開新語法 保證移植性。現代編譯器可忽略此類限制。

核心陷阱與規避方案

1. for 迴圈變數作用域


// C++98: 變數僅在迴圈內
// VC6: 變數洩漏到外層作用域
for (int i=0; i

2. 全域物件建構順序未定義 → 單例模式


// 危險:跨檔全域物件相依
// 安全:函式內靜態區域變數 (C++11 執行緒安全)
T& getInstance() {
    static T instance; // 首次呼叫初始化
    return instance;
}

註:單例解決建構順序,但解構順序仍有風險。

3. inline 函數限制

  • 避免內部使用 static 區域變數 (各編譯單元會有獨立副本)。
  • 避免可變參數 (...)。

4. 函式參數求值順序未定義


void foo(int a, int b);
int n = 1;
foo(++n, ++n); // a,b 值不確定 (可能 2,3 或 3,2)

// 規避:分離副作用
int a = ++n;
int b = ++n;
foo(a, b);

5. 模板特化/偏特化支援不足

舊編譯器可能不支援。避免複雜特化,改用標記類別/多載。

6. 模板繼承中存取基類成員


template class Base {
protected:
    typedef std::vector Container;
    Container data_;
};
template class Derived : public Base {
    using Base::Container;  // 必須引入
    using Base::data_;
    void func() {
        Container c;           // OK: 已引入
        // Container c;        // 錯誤: 未引入時依賴非標準查找
        data_.clear();         // OK: 已引入
        // this->data_.clear(); // 另一種寫法
    }
};

7. RTTI (typeid/type_info) 可移植性差

  • 舊編譯器可能不支援。
  • 標準對 type_info 規定極少,實作差異大 (如 name() 回傳字串格式)。
  • 若必用,僅用 operator==/operator!=。
  • 替代方案:自訂型別 ID (如 MFC CRuntimeClass, wxWidgets)。

8. 巢狀類別存取外部類別私有成員


// 錯誤:內部類別非友元
class Outer {
    int secret;
    class Inner { void f(Outer* o) { cout << o->secret; } };
};

// 正確:前置宣告 + 友元宣告
class Outer {
    int secret;
    class Inner; friend class Inner;
    class Inner { void f(Outer* o) { cout << o->secret; } };
};

9. 參數型別過近導致多義性


void foo(short); void foo(long);
foo(0); // 0 是 int,轉 short 與 long 皆為標準轉換 → 多義性

// 規避:避免此類多載組合,或用強型別包裝

10. 標準型別大小平台相關

  • int、wchar_t、long 大小隨平台變化。
  • 需固定大小用 int32_t 等定長型別。

11. 類別靜態常數成員舊編譯器不支援 → 用枚舉


class Foo {
    static const int MIN = 0;  // VC6 錯誤
    enum { MAX = 64 };         // 通用
};
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved