1. 程式人生 > >類和物件_繼承

類和物件_繼承

一、 繼承

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指標來識別成員資料屬於哪個物件。