c++隱藏

今天才知道c++繼承裏面的隱藏特性,真是孤陋寡聞了。

#include <iostream>
using namespace std;
class A
{
public:
     void print()
    {cout<<"A"<<endl;}
};

class B:public A
{
public:
    void print(int a)
    {cout<<"B"<<endl;}
};
int main()
{
    B b = B();
    b.print(); // 報錯,error: no matching function for call to 'B::print()' 
    // note: candidate: void B::print(int) note: candidate expects 1 argument, 0 provided
    // 有了print(int a) 把print()隱藏了
    B* b=new B();
    b->print(); // 報錯
}

隱藏的不光是成員函數,還可以是成員變量。

★在子類的內部或者外部(通過子類成員)訪問該成員,全部訪問的子類同名成員。

★在子類的內部或者外部(通過子類成員)訪問該同名的成員函數,調用的是子類的成員函數。

這裏“隱藏”是指派生類的函數屏蔽了與其同名的基類函數,規則如下:
(1)如果派生類的函數與基類的函數同名,但是參數不同。此時,不論有無virtual關鍵字,基類的函數將被隱藏(注意別與重載混淆)。
(2)如果派生類的函數與基類的函數同名,並且參數也相同,但是基類函數沒有virtual關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)。

原因

  • 因爲你繼承一個基類的時候,很多時候你是不知道這個基類裏面具體有哪些成員函數的(比如說你繼承的基類來自於某個類庫,或者大型項目中,可能因爲分工不同,你需要繼承的基類是別的開發人員做的),如果基類成員函數沒有被隱藏,就會被當成函數重載來處理。但是基類的重載函數,很可能會出現我們意料之外的處理結果。舉個例子。假如你寫了一個函數A,讀入的參數是一個浮點型的數據,返回值爲讀入參數的2倍。這時候碰巧基類裏面有個同名成員函數A,讀入的參數是一個整型的數據,但返回值爲讀入參數的3倍。這時候,你調用派生類的A函數,如果用戶輸入一個整型,按照你原本的設計,本應該是要把這個參數強制轉換爲浮點型返回它的2倍,但是因爲基類成員函數沒有被隱藏,所以就會當成函數重載處理,返回它的3倍。這樣就會與你原先的設計衝突了。

  • 不是隱藏,而是命名空間查找順序的問題.
    C++中,遇到一個函數調用,需要根據名字來確定調用的是哪一個函數,這時候如果派生類定義了該函數,就不會在基類的名字空間中去找.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章