避免掩蔽繼承而來的名稱

2021-07-09 14:03:30 字數 1377 閱讀 8020

此例內含一組混合了public和private名稱,以及一組成員變數和成員函式名稱。這些成員函式包括pure virtual,impure virtual和non-virtual三種。假設derived class內的mf4的實現**是這樣的:

void derived::mf4()

這裡編譯器看到這裡使用名稱mf2,必須估算它指涉什麼東西。編譯器的做法是查詢各個作用域。首先查詢local作用域,就是mf4覆蓋的作用域,沒用找到mf2,於是查詢外圍作用域,也就是class derived覆蓋的作用域,還是沒有找到mf2,於是再往外圍找,在base class找到。

再考慮前乙個例子,這次我們過載mf1和mf3,並且新增乙個新的mf3到derived。這裡發生的事情是:derived 過載了mf3,那是乙個繼承而來的non-virtual函式。如下:

以作用域為基礎的「名稱遮掩規則」並沒有改變,因此base class內所有名為mf1和mf3的函式被derived class內的mf1和mf3函式遮掩掉了。從名稱查詢看,base::mf1和base::mf3不再被derived繼承。

derived d;

int x

d.mf1(); //呼叫derived::mf1

d.mf1(x); //錯誤,derived::mf1遮掩了base::mf1

d.mf2(); //呼叫base::mf2

d.mf3(); //呼叫derived::mf3

d.mf3(x); //錯誤,呼叫derived::mf3()遮掩了base::mf3()

接著看:

d.mf1(); //呼叫derived::mf1

d.mf1(x); //呼叫base::mf1

d.mf2(); //呼叫base::mf2

d.mf3(); //呼叫derived::mf3

d.mf3(x); //呼叫base::mf3()

這意味著如果你繼承base class並加上過載函式,而你又希望重新定義或覆蓋其中一部分,那麼你必須為那些原本會被遮掩的每個名稱引入乙個using宣告,否則某些你希望繼承的名稱會被遮掩。

(來自effective c++)

避免遮掩繼承而來的名稱

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 避免繼承而來的名稱

避免繼承而來的名稱 一朵玫瑰叫任何名字還是一樣芬芳 莎士比亞 子類中查詢乙個成員的的名字的方法 1子類作用域 2 基類作用域 3 內含基類的名字空間 4 全域性 includeclass base void mf3 double class derived public base void mf3 ...