1.多載運算子和多載函式:
C++ 允許在同一作用域中的某個函式和運算子指定多個定義,分別稱為函式多載和運算子多載,
多載宣告是指一個與之前已經在該作用域內宣告過的函式或方法具有相同名稱的宣告,但是它們的引數串列和定義(實作)不相同,
當您呼叫一個多載函式或多載運算子時,編譯器通過把您所使用的引數型別與定義中的引數型別進行比較,決定選用最合適的定義,
選擇最合適的多載函式或多載運算子的程序,稱為多載決策,
a.函式多載:
在同一個作用域內,可以宣告幾個功能類似的同名函式,但是這些同名函式的形式引數(指引數的個數、型別或者順序)必須不同,您不能僅通過回傳型別的不同來多載函式,
b.運算子多載:
您可以重定義或多載大部分 C++ 內置的運算子,這樣,您就能使用自定義型別的運算子,
多載的運算子是帶有特殊名稱的函式,函式名是由關鍵字 operator 和其后要多載的運算子符號構成的,與其他函式一樣,多載運算子有一個回傳型別和一個引數串列,
詳細例子:https://www.runoob.com/cplusplus/cpp-overloading.html
2.多型:
多型按字面的意思就是多種形態,當類之間存在層次結構,并且類之間是通過繼承關聯時,就會用到多型,
C++ 多型意味著呼叫成員函式時,會根據呼叫函式的物件的型別來執行不同的函式,
例子:https://www.runoob.com/cplusplus/cpp-polymorphism.html
文字版解釋:
假設我們有個基類叫shape,成員函式area,而其兩個子類的成員函式也有area(同名),
如果你想呼叫兩個子類的函式area時候會發現程式仍然會呼叫shape(父類)的area函式,
導致錯誤輸出的原因是,呼叫函式 area() 被編譯器設定為基類中的版本,這就是所謂的靜態多型,或靜態鏈接 - 函式呼叫在程式執行前就準備好了,有時候這也被稱為早系結,因為 area() 函式在程式編譯期間就已經設定好了,
解決辦法就是 基類 的area函式宣告改成
virtual int area(){
}
此時,編譯器看的是指標的內容,而不是它的型別,因此,由于 tri 和 rec 類的物件的地址存盤在 *shape 中,所以會呼叫各自的 area() 函式,
正如您所看到的,每個子類都有一個函式 area() 的獨立實作,這就是多型的一般使用方式,有了多型,您可以有多個不同的類,都帶有同一個名稱但具有不同實作的函式,函式的引數甚至可以是相同的,
這套解決方案叫做 :
虛函式 :
是在基類中使用關鍵字 virtual 宣告的函式,在派生類中重新定義基類中定義的虛函式時,會告訴編譯器不要靜態鏈接到該函式,
我們想要的是在程式中任意點可以根據所呼叫的物件型別來選擇呼叫的函式,這種操作被稱為動態鏈接,或后期系結,
純虛函式:
您可能想要在基類中定義虛函式,以便在派生類中重新定義該函式更好地適用于物件,但是您在基類中又不能對虛函式給出有意義的實作,這個時候就會用到純虛函式,
virtual int area() = 0;
純虛函式一定沒有定義,純虛函式用來規范派生類的行為,即介面,包含純虛函式的類是抽象類,抽象類不能定義實體,但可以宣告指向實作該抽象類的具體類的指標或參考,
C++中, 虛函式可以為private, 并且可以被子類覆寫(因為虛函式表的傳遞),但子類不能呼叫父類的private虛函式,虛函式的多載性和它宣告的權限無關,
一個成員函式被定義為private屬性,標志著其只能被當前類的其他成員函式(或友元函式)所訪問,而virtual修飾符則強調父類的成員函式可以在子類中被重寫,因為重寫之時并沒有與父類發生任何的呼叫關系,故而重寫是被允許的,
編譯器不檢查虛函式的各類屬性,被virtual修飾的成員函式,不論他們是private、protect或是public的,都會被統一的放置到虛函式表中,對父類進行派生時,子類會繼承到擁有相同偏移地址的虛函式表(相同偏移地址指,各虛函式相對于VPTR指標的偏移),則子類就會被允許對這些虛函式進行多載,且多載時可以給多載函式定義新的屬性,例如public,其只標志著該多載函式在該子類中的訪問屬性為public,和父類的private屬性沒有任何關系!
純虛函式可以設計成私有的,不過這樣不允許在本類之外的非友元函式中直接呼叫它,子類中只有覆寫這種純虛函式的義務,卻沒有呼叫它的權利,
參考:https://www.runoob.com/cplusplus/cpp-polymorphism.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/83170.html
標籤:C++
