c++primer p499
「在基類和派生類中使用同一名字的成員函式,在派生類作用域中派生類成員將遮蔽基類成員,即使函式原型不同,基類成員也會被遮蔽:」
struct base
;struct derived: base
;int main()
注1:派生類中定義的函式也不過載基類中定義的成員。通過派生類物件呼叫函式時,實參必須與派生類中定義的版本相匹配,只有在派生類根本沒有定義該函式時,才考慮基類函式。
注2:如果派生類重定義了過載成員,則通過派生類只能訪問派生類中重定義的那些成員。
「派生類不用重定義所繼承的每乙個基類版本,它可以為過載成員提供using宣告。乙個using 宣告只能指定乙個名字,不能指定形參表。因此,為基類成員函式名稱而做的using宣告將改函式的所有過載例項加到派生類的作用域。」將所有名字加入作用域後,派生類只需要重定義本型別確實必須定義的那些函式。「
開始有點不理解,看了下林銳的高質量程式設計上的例項。
p250 成員函式的過載、覆蓋與隱藏
成員函式被過載的特徵:
(1)相同的範圍(在同乙個類中);
(2)函式名字相同;
(3)引數型別、順序或數目不同(包括const和非const引數);
(4)virtual 關鍵字可有可無。
覆蓋是指派生類函式覆蓋基類函式,特徵是:
(1)不同的範圍(分別位於派生類與基類);
(2)函式名字相同;
(3)引數相同;
(4)基類函式必須有virtual 關鍵字。
p251 令人迷惑的隱藏規則
」隱藏「是指派生類的成員函式遮蔽了與其同名的基類成員函式,具有規則:
(1)如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual
關鍵字,基類的函式將被隱藏(注意別與過載混淆)。
(2)如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual
關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)。
下段**中:
(1)函式derived::f(float)覆蓋了base::f(float)。
(2)函式derived::g(int) 隱藏了base::g(float),而不是過載。
(3)函式derived::h(float)隱藏了base::h(float),而不是覆蓋。
p253 擺脫隱藏class base
void g(float x)
void h(float x)
};class derived : public base
void g(int x)
void h(float x)
};int main(void)
class derived:public base
};
class base
;class derived:public base;/*
如果要讓pd->f(10)呼叫函式base::f(int )
1. 使用using宣告;
2. 把類derived修改如下
*///1. using 宣告
class derived:public base
;//2.
class derived:public base
}void test(void)
但是,隱藏規則的存在有會帶來好處:
(1)寫語句pd->f(10)的人可能真的想呼叫derived::f(char *)函式,只是他誤將引數寫錯了。有了隱藏規則,編譯器就可以明確指出錯誤,這未必不是好事。否則,編譯器會靜悄悄地將錯就錯,程式設計師將很難發現這個錯誤,流下禍根。
(2)假如類derived 有多個基類(多重繼承),有時搞不清楚哪些基類定義了函式f。如果沒有隱藏規則,那麼pd->f(10)可能會呼叫乙個出乎意料的基類函式f。儘管隱藏規則看起來不怎麼有道理,但它的確能消滅這些意外。
作用域與成員函式
作用域與成員函式 在基類和派生類中使用同一名字的成員函式,其行為與資料成員一樣 在派生類作用域中派生類成員將遮蔽基類成員。即使函式原型不同,基類成員也會被遮蔽。class base class child public base child c child cout 區域性作用域中宣告的函式不會過載...
函式與作用域
函式宣告 function add a,b return a b 函式表示式 function variable 函式變數 varadd function a,b ief immediately excuted function 立即執行函式 function first class functio...
塊級作用域與函式作用域
函式作用域 變數在定義的環境中以及巢狀的子函式中處處可見 塊級作用域 變數在離開定義的塊級 後立即被 在es6之前,js的作用域只有兩種 函式作用域和全域性作用域。使用var宣告的變數,都存在變數提公升的過程。console.log a undefined console.log c undefin...