類和物件_繼承
阿新 • • 發佈:2018-11-03
一、 繼承
1. 繼承關係是類中成員方法的關係:
class Base { public: void show() //方法1 { cout<<Base::show()<<endl; } void show(int a) //方法2 { cout<<Base::show(int a)<<endl; } } class Derive { public: void show() //方法3 { cout<<Derive::show()<<endl; } }
- 過載:同作用域是前提,函式名相同,引數型別列表不同。正如方法1和方法2。
- 隱藏:父類和子類的同名方法,在子類作用域中被隱藏。正如方法1和方法3。
- 覆蓋:子類中同名,同參數型別列表,同返回值的成員方法覆蓋子類中的虛成員方法。
2. 相互賦值,記住一點——“寧濫勿缺”
父類物件賦值給子類物件。×不可行- 子類物件賦值給父類物件。
子類指標指向父類物件。×不可行- 父類指標指向子類物件。
為什麼第一條和第三條不可行?這不涉及語法——試想一下,如果子類對父類進行擴充,父類物件給子類物件賦值,擴充部分的值從何而來?總不能賦值結束子類物件都已經生成了卻還是不完整的吧?第一條不可行原因在於此。子類指標指向父類物件,如果想通過子類指標訪問子類擴充部分的內容(變數和成員方法),而父類物件是沒有的,會出錯。第三條不可行的原因在於此。
3. 四種強轉方式(有機會自己實現)
- const_cast:去掉const屬性。
- static_cast:編譯器認為安全的強轉方式。
- reinterpret_cast:強制型別轉換
- dynamic_cast:繼承關係中專用的強轉, RTTI(Run-Time Type Identification執行時型別識別)。模板型別引數必須是void*或者指向類型別的指標(引用)——類型別必須具有RTTI。
4. 虛擬函式
虛擬函式呼叫必須依賴物件內部的虛擬函式表。
建構函式:
物件沒有構造完成=>物件不完整。建構函式不可以實現為虛擬函式。建構函式內部不可以多型呼叫虛擬函式,因為物件不完整。
解構函式:
可以實現為虛擬函式,但是解構函式內部不可以多型呼叫虛擬函式,因為物件不完整。
5. this指標
物件之所以能呼叫成員函式,是因為類的成員函式在編譯時,編譯器自動在引數型別列表第一個位置新增this指標來識別成員資料屬於哪個物件。