class B {
virtual void test() { std::cout << "B::test()\n"; }
virtual void test(int x) { std::cout << "B::test(int)\n"; }
};
class D : public B {
virtual void test() { std::cout << "D::test()\n"; } // 僅覆寫無參數版
};
int main() {
D d;
d.test(); // OK
d.test(17); // 編譯錯誤:C2660 'test' function does not take 1 parameters
}
C++ 名稱查找遵循「由內而外」原則:
D 類別作用域找到 test 名稱。B。D 中僅找到 test(),參數不匹配 test(17),報錯。這稱為**名稱遮蔽**,非多載解析失敗。標準設計意圖:避免在深層繼承鏈中意外匹配到語意不符的多載版本。
class D : public B {
public:
using B::test; // 將 B 所有 test 多載引入 D 作用域
virtual void test() { std::cout << "D::test()\n"; }
};
優點: 基類新增 test(double) 等多載自動繼承,無需修改 D。
缺點: 所有基類 test 多載皆公開,若需隱藏特定版本需額外處理。
class D : public B {
public:
virtual void test(int x) { B::test(x); } // 手動轉發
virtual void test() { std::cout << "D::test()\n"; }
};
優點: 精確控制公開哪些多載版本。
缺點: 基類新增多載時需同步更新衍生類別。
class B {
public:
void func1();
void func2(double);
virtual void test();
virtual void test(int);
};
class D : private B { // 完全隱藏 B 介面
public:
using B::test; // 僅選擇性公開 test 多載集合
};
此技巧常用於「介面繼承」而非「實作繼承」場景。
using Base::Func 是標準、優雅的解除遮蔽方式。