c++之繼承與派生

(一)繼承的概念:

繼承(Inheritance)可以理解爲一個類從另一個類獲取成員變量和成員函數的過程。例如類 B 繼承於類 A,那麼 B 就擁有 A 的成員變量和成員函數。被繼承的類稱爲父類或基類,繼承的類稱爲子類或派生類。


(二)繼承權限與繼承方式

1.C++繼承的一般語法爲:

class 派生類名:[繼承方式] 基類名
{
    派生類新增加的成員
};
繼承方式限定了基類成員在派生類中的訪問權限,包括 public(公有的)、private(私有的)和 protected(受保護的)。此項是可選項,如果不寫,默認爲 private(成員變量和成員函數默認也是 private)。
 
現在我們知道,public、protected、private 三個關鍵字除了可以修飾類的成員,還可以指定繼承方式。


2.繼承權限

1) public繼承方式
基類中所有 public 成員在派生類中爲 public 屬性;
基類中所有 protected 成員在派生類中爲 protected 屬性;
基類中所有 private 成員在派生類中不能使用。
 
2) protected繼承方式
基類中的所有 public 成員在派生類中爲 protected 屬性;
基類中的所有 protected 成員在派生類中爲 protected 屬性;
基類中的所有 private 成員在派生類中不能使用。
 
3) private繼承方式
基類中的所有 public 成員在派生類中均爲 private 屬性;
基類中的所有 protected 成員在派生類中均爲 private 屬性;
基類中的所有 private 成員在派生類中不能使用。


(三)繼承中的構造析構調用原則 

1構造析構調用原則 

1)子類對象在創建時會首先調用父類的構造函數
2)父類構造函數執行結束後,執行子類的構造函數
3)當父類的構造函數有參數時,需要在子類的初始化列表中顯示調用
4)析構函數調用的先後順序與構造函數相反

2 繼承與組合混搭下的調用原則

原則:   先構造父類,再構造成員變量、最後構造自己
             先析構自己,在析構成員變量、最後析構父類
             //先構造的對象,後釋放


#include 
using namespace std;
 
class Object
{
public:
    Object(int a)
    {
        this->a = a;
        cout << "Object 構造函數 : "  << a <<  endl;
    }
 
    ~Object()
    {
        cout << "Object 析構函數: " << this->a << endl;
    }
private:
    int a;
};
 
class Parent
{
public:
    Parent(int a, int b)
    {
        cout << "parent 構造函數" << endl;
    }
    ~Parent()
    {
        cout << "parent 析構函數" << endl;
    }
private:
    int a;
    int b;
};
 
class Child : public Parent
{
public:
    Child(int c):obj1(1), Parent(2, 3),  obj2(2)
    {
        cout << "child 構造函數" << endl;
    }
    ~Child()
    {
        cout << "child 析構函數" << endl;
    }
 
private:
    int c;
    Object obj1;
    Object obj2;
};
 
int main()
{
    {
        Child ch(4);
    }
 
    return 0;
}

結果是先構造父類,在構造混搭obj1,obj2,在構造自己,析構正好相反


3繼承中的同名成員變量處理方法 

1)當子類成員變量與父類成員變量同名時
2)子類依然從父類繼承同名成員
3)在子類中通過作用域分辨符::進行同名成員區分(在派生類中使用基類的同名成員,顯式地使用類名限定符) 
4)同名成員存儲在內存中的不同位置


4.派生類中的static關鍵字

繼承和static關鍵字在一起會產生什麼現象哪?
理論知識
基類定義的靜態成員,將被所有派生類共享
根據靜態成員自身的訪問特性和派生類的繼承方式,在類層次體系中具有不同的訪問性質 (遵守派生類的訪問控制)
派生類中訪問靜態成員,用以下形式顯式說明:類名 :: 成員   或通過對象訪問   對象名 . 成員 
總結:
1> static函數也遵守3個訪問原則
2> static易犯錯誤(不但要初始化,更重要的顯示的告訴編譯器分配內存)
 


(四)多繼承

1. 一個類有多個直接基類的繼承關係稱爲多繼承

     多繼承聲明語法
    class  派生類名 : 訪問控制  基類名1 ,  訪問控制  基類名2 ,  … , 訪問控制  基類名n
    {
         數據成員和成員函數聲明
    };
    類 C 可以根據訪問控制同時繼承類 A 和類 B 的成員,並添加自己的成員


2. 多繼承的派生類的構造和訪問:

多個基類的派生類構造函數可以用初始式調用基類構造函數初始化數據成員
執行順序與單繼承構造函數情況類似。多個直接基類構造函數執行順序取決於定義派生類時指定的各個繼承基類的順序。
 一個派生類對象擁有多個直接或間接基類的成員。不同名成員訪問不會出現二義性。如果不同的基類有同名成員,派生類對象訪問時應該加以識別。


3.虛繼承

如果一個派生類從多個基類派生,而這些基類又有一個共同的基類,則在對該基類中聲明的名字進行訪問時,可能產生二義性
  如果在多條繼承路徑上有一個公共的基類,那麼在繼承路徑的某處匯合點,這個公共基類就會在派生類的對象中產生多個基類子對象
  要使這個公共基類在派生類中只產生一個子對象,必須對這個基類聲明爲虛繼承,使這個基類成爲虛基類。
  虛繼承聲明使用關鍵字       virtual


4.C++向上轉型原則:

類其實也是一種數據類型,也可以發生數據類型轉換,不過這種轉換只有在基類和派生類之間纔有意義,並且只能將派生類賦值給基類,包括將派生類對象賦值給基類對象、將派生類指針賦值給基類指針、將派生類引用賦值給基類引用,這在 C++ 中稱爲向上轉型(Upcasting)。相應地,將基類賦值給派生類稱爲向下(Downcasting)。

 
向上轉型非常安全,可以由編譯器自動完成;向下轉型有風險,需要程序員手動干預。


5.兼容性原則:

類型兼容規則是指在需要基類對象的任何地方,都可以使用公有派生類的對象來替代。通過公有繼承,派生類得到了基類中除構造函數、析構函數之外的所有成員。這樣,公有派生類實際就具備了基類的所有功能,凡是基類能解決的問題,公有派生類都可以解決。
類型兼容規則中所指的替代包括以下情況:
子類對象可以當作父類對象使用
子類對象可以直接賦值給父類對象
子類對象可以直接初始化父類對象
父類指針可以直接指向子類對象
父類引用可以直接引用子類對象
在替代之後,派生類對象就可以作爲基類的對象使用,但是隻能使用從基類繼承的成員。
類型兼容規則是多態性的重要基礎之一。


(五)總結

1繼承是面向對象程序設計實現軟件重用的重要方法。程序員可以在已有基類的基礎上定義新的派生類。
2 單繼承的派生類只有一個基類。多繼承的派生類有多個基類。
3 派生類對基類成員的訪問由繼承方式和成員性質決定。
4創建派生類對象時,先調用基類構造函數初始化派生類中的基類成員。調用析構函數的次序和調用構造函數的次序相反。
5 C++提供虛繼承機制,防止類繼承關係中成員訪問的二義性。
6 多繼承提供了軟件重用的強大功能,也增加了程序的複雜性。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章