c++入門---------繼承篇

學完c++面向對象基礎後,緊隨其後的便是繼承了,可想而知繼承的重要性!


一. 什麼是繼承

  1. 對於剛剛學完面向對象編程基礎的朋友,看到這裏的第一個問題就是什麼是繼承,這個可以直接從字面意思上理解,你可以繼承其他人的財產,只要別人同意,同樣對象也可以繼承另一個對象的函數與變量。
  2. 在繼承中,被繼承的類稱爲基類或者父類,繼承該類的類稱爲子類或者派生類。
  3. 繼承可以最大限度的實現代碼的複用。
  4. 下面給出繼承的簡單實例。
#include<iostream>
using namespace std;
class A{
private:
	int x;
	int y;
public:
	A(int a,int b)
	{
		x = a;
		b = b;
	};
	void disp()
	{
		cout<<x,y<<endl;
	}
};

class B:public A    #類B繼承類A
{
private:
	int z;
public:
	B(int a,int b, int c):A(a,b),z=c;	
};
int main()
{
	B a(1,2,3);
	a.disp();   #類B可以調用類A的函數。

	return ;
}

在上述代碼中,我們定義了類A和類B,類B繼承類A,既類A稱爲父類或者基類,類B稱爲子類或者派生類。

二. 基類和派生類

  1. 基類

    1. 直接基類:B繼承A,則A爲B的直接基類。
    2. 間接基類:C繼承B,B繼承A,則A爲C的間接基類。
  2. public和private派生

    1. 在兩種派生方法當中,主要的區別就是基類對象在派生類中是私有的還是公開的,下面這個表格中歸納了一下。
派生方法 private private public public
基類成員 private成員 public成員 private成員 public成員
派生類中 不可見 private 不可見 public
外部 不可見 不可見 不可見 可見

可見無論採用那種方法基類的private成員在派生類中和外部都是不可見的,而public成員在private派生方法中,在派生類中是private的,public中的派生類中是public的。
3. protected派生
在上面的派生中,如果派生類在往下派生一類的話,那麼基類的變量便會不可以訪問了,爲了解決這個問題,由此產生了protected派生。

protected protected protected
private protected public
不可見 private protected
不可見 不可見 不可見

三. 多基派生

  1. 一個類繼承其他的多個類稱爲多基派生。其聲明和定義爲
派生類名(參數表):基類名1(參數),基類名2(參數),.....,基類名n(參數n)
{
private:

public:
};
  1. 在多派生中會存在一個二義性問題,下面通過代碼來說明。
#include<iostream>
using namespace std;
class A{
	public:
		void print(){
		cout<<"hello c++"<<endl;
		}
};

class B{
	public:
		void print(){
		count<<"hello,c"<<endl;
		}
};

class C:public A,public B
{
	public:
		void disp()
		{
		print();
		}
};
int main()
{
	C a;
	a.disp();
	a.print();
	return 0;
}

在上述代碼中,類A和類B中都有print函數,類C繼承了A,B,在調用print函數的時候,編譯器就不知道是那個類中的print函數,這樣就出現了二義性。這個問題可以通過成員限定符來消除二義性。

a.A::print();

四. 虛基類

  1. 虛基類又是爲了解決什麼問題呢?這裏四個類A,B,C,D,假如說,類B繼承類A,類C也繼承類A,類D繼承類B和類C,這裏便會出現一個問題,在類D中,會有兩個類A的複製。
  2. 這樣也會帶來二義性。例如說,在類D中要調用類A中的函數,那會會出現是通過類B再到類A,還是通過類C再到類B呢?這便產生了二義性。
  3. 我們可以通過聲明虛基類來消除類A在內存的雙重複制,虛基類的定義爲:
class 派生類名:virtual 派生方式 基類名
{
};
  1. 在回到上面的問題中,這時候如果我們類B繼承的是虛基類A,類C繼承的虛基類A,類D繼承類B和類C,那麼便不會出現內存中出現兩個類A了,從而取消了二義性。

五. 派生類的構造函數和析構函數

派生時,由於構造函數和析構函數是不能被繼承的,所以對派生類我們需要重新定義。在創建派生類對象時,系統首先通過派生類的析構函數來調用基類的構造函數,完成基類成員的初始化,而後對派生類中新增的成員進行初始化。

  1. 派生類構造函數的一般格式爲
    派生類名 (派生類構造函數參數列表): 基類構造函數(基類構造函數參數列表){};

  2. 必須將基類的構造函數放在派生類的初始化表達式中,一調用基類構造函數完成基類數據成員的初始化,派生類構造函數實現的功能如下:

    1. 完成對象所佔整塊內存的開闢,由系統在構造函數時自動完成。
    2. 調用基類的構造函數完成基類成員的初始化。
    3. 若派生類中含對象成員、const成員或引用成員,則必須在初始化表中初始化。
    4. 派生類構造函數體執行。
  3. 派生類的析構函數

    1. 在對象被刪除的時候,自動調用析構函數,其調順序爲先派生類,後基類。

Thank for your reading!

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