[C/C++]覆蓋與隱藏

  • ①類的名字查詢邏輯:前後有繼承關係的類,其作用域實際上是嵌套的,即雖然我們寫成兩個類,父類和子類,看上去好像是分離的,實際上,他們就是另一種我們常見的類的關係,就是嵌套類。當我們申請了一個子類的對象,調用其中的一個繼承而來的公有函數的時候,編譯器實際上是首先在子類中根據函數的名稱進行查找,查找不到的話,再到他的上一層的作用域中進行查找的,這樣一直向上嵌套的查找一直到基類,所以基於這種查找邏輯就可能引發一個問題,就是按照名字來查找,而完全不去看後面的參數列表的話,那麼當在子類和父類都定義相同名字,而不同參數的函數的時候,就會出現問題,到底是繼續查查看父類還是就是直接用子類了?C++提供了兩種機制,一種是虛函數機制,如果用virtual聲明成了虛函數,即走動態綁定邏輯,如果不是虛函數,即這個名字不在虛函數列表中,則走普通邏輯,因此引發出了兩種進一步的操作,即覆蓋和隱藏。
  • ②覆蓋:覆蓋的意思其實就是對於虛函數在子類中進行重寫,這種寫法其實和編譯器的查找邏輯就沒有關係了,程序在運行的過程中去尋找那個函數的入口地址,這個可以認爲在編譯階段只是檢查一下有沒有這個函數就行了,在執行階段,其實完全按照執行階段的邏輯在運行,這種方式稱爲覆蓋,可以認爲是基於實際的,實際是哪個內存對象,他的虛函數列表中實際是什麼函數,就調用什麼函數。
  • ③隱藏:如果不是虛函數,是普通函數,這個時候就走前面的查找邏輯了,因此子類中的同名函數會隱藏父類中的函數,如果同樣用父類指針指向一個子類對象,這個時候是非虛函數,並且子類中有實現這個函數,那麼還是先從內層的開始調用即調用子類的,但是區別在於,如果在子類中的函數參數列表和調用的參數不同,這個時候會報錯,而不是再去父類中尋找有沒有對應的參數列表的函數。④總結一下的話,對於非虛函數,編譯器匹配實際上由兩輪邏輯,第一輪,通過名稱來確定類的域,完全通過名字來確定,所以這個稱爲隱藏確定下來以後,父類的子類的就不看了,第二輪是在這個域中匹配對應的參數列表最最匹配的函數,這個其實是重載的工作,和前面的匹配工作沒有什麼關聯了,主要就是這個邏輯。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章