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

高品質 C++/C 程式設計指南:隱藏規則詳解、陷阱案例與 using 宣告解除隱藏

     編輯:VC 教學

隱藏規則兩大情況

  1. 衍生類函數與基類函數同名、參數不同:無論 virtual,基類同名函數全部被隱藏(非多載)。
  2. 衍生類函數與基類函數同名、參數相同,但基類非 virtual:基類函數被隱藏(非覆蓋)。

經典陷阱:衍生類新增 overload 導致基類 overload 消失


class Base { public: void f(int); };
class Derived : public Base { public: void f(char*); };

Derived* pd = new Derived;
pd->f(10); // Error: Base::f(int) 被 Derived::f(char*) 隱藏,10 無法轉 char*

隱藏存在的理由

  • 防止參數寫錯時靜默呼叫非預期函數(編譯器報錯提前發現)。
  • 多重繼承時避免同名基類函數產生歧義(隱藏消除意外匹配)。

解除隱藏:using 宣告


class Derived : public Base {
public:
    void f(char*);
    using Base::f; // 將 Base::f(int) 引入 Derived 作用域
};
// 現在 pd->f(10) 正常呼叫 Base::f(int)

using Base::f; 會引入基類所有名為 f 的多載,衍生類同名多載參與多載解析。

完整修正範例


class Base {
public:
    virtual void f(float) { cout << "Base::f(float)"; }
    void g(float) { cout << "Base::g(float)"; }
    void h(float) { cout << "Base::h(float)"; }
};

class Derived : public Base {
public:
    virtual void f(float) { cout << "Derived::f(float)"; } // 覆蓋
    void g(int) { cout << "Derived::g(int)"; }
    void h(float) { cout << "Derived::h(float)"; }

    using Base::g; // 解除 g 隱藏,恢復 Base::g(float) 可用
    using Base::h; // 解除 h 隱藏
};

最佳實務

  • 衍生類新增同名函數時,預設加上 using Base::FuncName;,除非確定要隱藏。
  • 覆蓋虛函數務必加 override(C++11)編譯期檢查簽章。
  • 程式碼審查重點檢查「同名不同參」是否為有意隱藏。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved