20180321 c++ 避免遮掩繼承而來的名稱
c++的名稱遮掩規則(name-hiding relue)所做的唯一事情就是:遮掩名稱。至於名稱是否是相同或不同的型別,並不重要,如double型別的區域性變數x遮掩了int型別的全域性變數x。
現在考慮繼承關係:
eg:class base
class derived:public base
上述**中,基類中的所有名為mf1和mf3的函式都被派生類的mf1和mf3函式遮掩掉了。從名稱查詢觀點來看,base::mf1和base::mf3不再被派生類繼承!
derived d;
int x;
...d.mf1();//沒問題,呼叫derived::mf1
d.mf1(x);//錯誤,因為derived::mf1已經遮掩了bsase:mf1
d.mf2();//沒問題,呼叫base::mf2
d.mf3();//沒問題,呼叫derived::mf3
d.mf3(x);//錯誤,因為derived::mf3已經遮掩了bsase:mf3
你可以使用using宣告式達成目標:
eg:class base
class derived:public base
下面進行如下操作:
derived d;
int x;
...d.mf1();//仍然沒問題,呼叫derived::mf1
d.mf1(x);//現在沒問題了,呼叫derived::mf1
d.mf2();//仍然沒問題,仍然呼叫base::mf2
d.mf3();//沒問題,呼叫derived::mf3
d.mf3(x);//現在沒問題了,呼叫base:mf3
這意味著,若你繼承父類並加上過載函式,而你又希望重新定義或覆寫其中一部分,那麼你必須為那些原本會被遮掩的每個名稱引入乙個using宣告式,否則某些你希望繼承的名稱會被遮掩。
有時候當不想繼承父類的所有函式時,是可以使用乙個簡單的轉換函式(forwarding function),eg:
class base;
...derived d;
int x;
d.mf1();//很好,呼叫的是derived::mf1
d.mf1();//錯誤! base::mf1()被遮掩了
inline轉換函式(forwarding function)的另乙個用途是為那些不支援using宣告式(注:這並非正常行為)的老舊編譯器另闢一條新路,將繼承而得的名稱匯入派生類作用域中。
注意:1、派生類裡的名稱會遮掩基類裡的名稱。在共有繼承下從來沒有人希望入如此。
2、為了讓被遮掩的名稱重見天日,可使用using生命式或轉換函式(forwarding functions)。
避免遮掩繼承而來的名稱
public virtual void mf1 0 virtual void mf1 int virtual void mf2 void mf3 void mf3 double class derived public base derived d int x d.mf1 fine,calls de...
避免遮掩繼承而來的名稱
我們知道,當位於乙個derived class成員函式內指涉 refer to base class內的某物 也許是個成員函式 typedef 或是成員變數 時,編譯器可以找出我們所指的東西,因為derived class繼承了宣告與base class內的所有東西。但是讓我們看下面一段 inclu...
條款33 避免遮掩繼承而來的名稱
問題 base class 中的所有名為 mf1 和 mf3 的函式被 derived class 中的名為 mf1 和 mf3 的函式覆蓋。從名字搜尋的觀點看,base mf1 和 base mf3 不再被 derived 繼承!就像你看到的,即使 base 和 derived classes 中...