C++中類與類之間存在着兩種名稱遮蓋關系,變量遮蓋、函數遮蓋。其本質都是名字的查找方式導緻的,當編譯器要找一個名字,它一旦找到一個相符的名字,就不會往下找了,是以遮掩本質上是優先查找那個名字的問題。 查找名字時,編譯器先從子類開始,一旦找到了,就不再繼續查找。無論普通函數,虛函數,還是純虛函數,結果都是輸出子類的函數調用。 避免遮掩繼承而來的名稱是因為,你在使用public繼承而又不繼承那些重載函數,就是違反base和derive class之間的 is 關系。
如果非要通路父類的方法,用兩種方法可以實作
1. 使用using Base::func();聲明
2. 定義轉交函數
- //:采用using聲明,使查找範圍擴大至父類指定的函數:
- class Base
- {
- public:
- void CommonFunction(){cout << "Base::CommonFunction()" << endl;}
- void virtual VirtualFunction(){cout << "Base::VirturalFunction()" << endl;}
- void virtual VirtualFunction(int x){cout << "Base::VirtualFunction() With Parms" << endl;}
- void virtual PureVirtualFunction() = 0;
- };
-
- class Derived: public Base
- {
- public:
- using Base::VirtualFunction; // 第一級查找也要包括Base::VirtualFunction
- void CommonFunction(){cout << "Derived::CommonFunction()" << endl;}
- void virtual VirtualFunction(){cout << "Derived::VirturalFunction()" << endl;}
- void virtual PureVirtualFunction(){cout << "Derived::PureVirtualFunction()" << endl;}
- };
-
- int main()
- {
- Derived d;
- d.VirtualFunction(3); // 這樣沒問題了,編譯器會把父類作用域裡面的函數名VirtualFunciton也納入第一批查找範圍,這樣就能發現其實是父類的函數與main中的調用比對得更好(因為有一個形參),這樣會輸出Base::VirtualFunction() With Parms
- return 0;
- }
- //:使用轉交函數強制指定父類的作用域
- class Base
- {
- public:
- void CommonFunction(){cout << "Base::CommonFunction()" << endl;}
- void virtual VirtualFunction(){cout << "Base::VirturalFunction()" << endl;}
- void virtual VirtualFunction(int x){cout << "Base::VirtualFunction() With Parms" << endl;}
- void virtual PureVirtualFunction() = 0;
- };
- class Derived: public Base
- {
- public:
- using Base::VirtualFunction;
- void CommonFunction(){cout << "Derived::CommonFunction()" << endl;}
- void virtual VirtualFunction(){cout << "Derived::VirturalFunction()" << endl;}
- void virtual PureVirtualFunction(int x){cout << "Derived::PureVirtualFunction()" << endl;}
- void virtual VirtualFunction(int x){Base::VirtualFunction(x)};
- };
- int main()
- {
- Derived d;
- d.VirtualFunction(3); // 輸出Base::VirtualFunction() With Parms
- return 0;
- }
總結: 派生類的名字會遮蓋基類的名字
為了讓遮蓋的名字重見天日,可以用using聲明或者轉交函數。
來自為知筆記(Wiz)