天天看點

避免遮掩繼承而來的名稱

     C++中類與類之間存在着兩種名稱遮蓋關系,變量遮蓋、函數遮蓋。其本質都是名字的查找方式導緻的,當編譯器要找一個名字,它一旦找到一個相符的名字,就不會往下找了,是以遮掩本質上是優先查找那個名字的問題。    查找名字時,編譯器先從子類開始,一旦找到了,就不再繼續查找。無論普通函數,虛函數,還是純虛函數,結果都是輸出子類的函數調用。 避免遮掩繼承而來的名稱是因為,你在使用public繼承而又不繼承那些重載函數,就是違反base和derive class之間的 is 關系。

    如果非要通路父類的方法,用兩種方法可以實作

    1. 使用using Base::func();聲明

    2. 定義轉交函數

  1. //:采用using聲明,使查找範圍擴大至父類指定的函數:
  2. class Base
  3. {
  4. public:
  5. void CommonFunction(){cout << "Base::CommonFunction()" << endl;}
  6. void virtual VirtualFunction(){cout << "Base::VirturalFunction()" << endl;}
  7. void virtual VirtualFunction(int x){cout << "Base::VirtualFunction() With Parms" << endl;}
  8. void virtual PureVirtualFunction() = 0;
  9. };
  10. class Derived: public Base
  11. {
  12. public:
  13. using Base::VirtualFunction; // 第一級查找也要包括Base::VirtualFunction
  14. void CommonFunction(){cout << "Derived::CommonFunction()" << endl;}
  15. void virtual VirtualFunction(){cout << "Derived::VirturalFunction()" << endl;}
  16. void virtual PureVirtualFunction(){cout << "Derived::PureVirtualFunction()" << endl;}
  17. };
  18. int main()
  19. {
  20. Derived d;
  21. d.VirtualFunction(3); // 這樣沒問題了,編譯器會把父類作用域裡面的函數名VirtualFunciton也納入第一批查找範圍,這樣就能發現其實是父類的函數與main中的調用比對得更好(因為有一個形參),這樣會輸出Base::VirtualFunction() With Parms
  22. return 0;
  23. }
  1. //:使用轉交函數強制指定父類的作用域
  2. class Base
  3. {
  4. public:
  5. void CommonFunction(){cout << "Base::CommonFunction()" << endl;}
  6. void virtual VirtualFunction(){cout << "Base::VirturalFunction()" << endl;}
  7. void virtual VirtualFunction(int x){cout << "Base::VirtualFunction() With Parms" << endl;}
  8. void virtual PureVirtualFunction() = 0;
  9. };
  10. class Derived: public Base
  11. {
  12. public:
  13. using Base::VirtualFunction;
  14. void CommonFunction(){cout << "Derived::CommonFunction()" << endl;}
  15. void virtual VirtualFunction(){cout << "Derived::VirturalFunction()" << endl;}
  16. void virtual PureVirtualFunction(int x){cout << "Derived::PureVirtualFunction()" << endl;}
  17. void virtual VirtualFunction(int x){Base::VirtualFunction(x)};
  18. };
  19. int main()
  20. {
  21. Derived d;
  22. d.VirtualFunction(3); // 輸出Base::VirtualFunction() With Parms
  23. return 0;
  24. }

總結: 派生類的名字會遮蓋基類的名字

            為了讓遮蓋的名字重見天日,可以用using聲明或者轉交函數。

來自為知筆記(Wiz)