繼承中的名字隱藏、重定義、以及重定義與重載的區別


繼承中的名字隱藏

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,那叫重定義)

多態是在運行期間根據具體對象的類型決定函數調用

重寫的同時一般會伴隨發生函數重定義

 

函數重定義

必須發生於父類和子類之間

重定義不一定是多態

 

 

 

 

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