C++之過載覆蓋和隱藏

紅城客棧藍精靈發表於2019-05-17

繼承體系下同名成員函式的三種關係

  • 過載
  1. 在同一作用域內
  2. 函式名相同,引數列表不同(分三種情況:引數個數不同,引數型別不同,引數個數和型別都不同)
  3. 返回值型別可以相同也可以不同
  • 重寫(覆蓋)
  1. 在不同作用域內,分別在父類和子類
  2. 函式名相同,引數列表相同,返回值型別相同,協變除外(下面會介紹什麼是協變)
  3. 基類函式必須有virtual關鍵字修飾
  4. 父子類中函式的訪問修飾符可以不同
  • 重定義(隱藏)
  1. 在不同的作用域內,分別是父類和子類
  2. 函式名相同
  3. 在基類和派生類中只要不構成重寫的都是重定義

過載

C++中函式過載達到的效果:

呼叫函式名相同的函式,根據實參的型別和個數選擇相應的實現函式體執行。

函式過載是一種靜態多型,或者稱之為靜態聯編、靜態繫結、靜態決議,其實都一樣。

重寫/覆蓋

在子類中定義一個與父類中完全相同的虛擬函式:

  1. 父類和子類中的虛擬函式,函式名、引數個數、引數型別以及返回值型別都相同,構成重寫。
  2. 子類中的虛擬函式與父類中的虛擬函式,函式名、引數個數和型別都相同,只是返回值不同,父類的虛擬函式返回父類的指標或引用,子類虛擬函式返回子類的指標或引用,這種情況下也構成重寫,我們稱之為協變

C++中函式重寫達到的效果:

在子類中重寫了父類的虛擬函式,則子類物件呼叫該重寫函式時從子類內部呼叫,而不是從父類繼承,是一種動態多型。

在子類中重寫了父類的虛擬函式,如果用一個父類指標或引用指向子類物件,那麼該指標呼叫的是重寫的虛擬函式,也即是子類的虛擬函式, 而如果一個父類指標指向父類物件,則呼叫父類的虛擬函式。

重定義/隱藏

指的是在不同作用域內,函式名相同,但不構成重寫的則構成重定義。不僅僅是值類的成員函式,也可以是類的成員變數。

C++中重定義達到的效果:

如果再父類和子類中有相同名字的成員,子類中會將父類成員隱藏,此時無論在子類內部還是外部,通過子類成員會物件訪問該成員,訪問到的都是子類同名成員。

如果再子類內部或外部通過子類成員訪問同名成員函式,則需要根據函式呼叫的規則來呼叫子類的同名成員函式,否則呼叫失敗。

相關文章