繼承中的名字隱藏
1.基類同名函數被隱藏
對於下面的代碼
class P
{
public:
void f() {}
};
class C :public P
{
public:
void f(int x) {}
};
int main()
{
C c;
c.f();
}
g++編譯結果:
NameHiding.cpp:13:7: error: no matching function for call to 'C::f()'
(Visual C++編譯結果:應該也是錯的)
這就是子類的同名函數隱藏了父類的同名函數(只同名就可以)
1.1. 內部作用域的名字隱藏外部作用域的(同名)名字)
(1) 派生類視作內部作用域
(2) 基類視作外部作用域
2. Why?
(1) 避免某些潛在的危險行爲
(2) 每個類在創建時,它的函數名都是寫在一張乾淨的白紙上面,不會被基類函數名干擾
重定義函數
1. 重定義函數
子類重新定義父類中有相同名稱的非虛函數 ( 參數列表可以不同 ) 重定義後子類調用的函數是子類自己的函數,父類的函數會被隱藏。名字隱藏特性。如果想調用父類的該同名函數,需要用父類加上作用域來指定調用的函數。
2. Redefine (重定義)
3. 重定義與重載
3.1. 重載函數
3.1.1. 多個函數名字相同
3.1.2. 但至少一個特徵不同
(1) 參數類型
(2)參數數量
(3) 參數順序
3.2. 重定義函數
3.2.1.函數特徵相同
(1) 同名)
(2) 同參數:類型,數量和順序
(3) 返回值類型
3.2.2. 在基類和派生類中分別定義
雖然與上面重複,但還是總結如下爲好:
函數重載:
必須在一個類中進行(子類無法重載父類中的函數)
子類無法重載父類的函數,父類同名函數將被子類的同名函數覆蓋
重載是在編譯期間根據參數類型,順序,個數決定的函數調用
函數重寫
必須發生於父類和子類之間
並且父類和子類中的函數必須有完全相同的函數簽名
使用virtual聲明之後能夠產生多態(如果不使用virtual,那叫重定義)
多態是在運行期間根據具體對象的類型決定函數調用
重寫的同時一般會伴隨發生函數重定義
函數重定義
必須發生於父類和子類之間
重定義不一定是多態