1. 程式人生 > 其它 >對於c++繼承的淺理解

對於c++繼承的淺理解

技術標籤:c++繼承

1、繼承的語法
我們把被繼承的類稱為基類或者父類,繼承父類的稱為派生類或者子類。
他的語法是 class 子類:繼承方式 父類1,父類2…{};
2、繼承方式
繼承方式和類中的許可權一樣,有public,protected,private三種

class Base1{
	public:
		int m_A;
	protected:
		int m_B;
	private:
		int m_C;
};

1、public繼承 子類可以訪問父類中的公共成員和保護成員,但不可訪問私有成員,子類中繼承的成員的許可權和父類相同。

class son1:public Base1{
public: void func(){ m_A=10; m_B=10; // m_C=10; // cout<<m_C<<endl; 錯誤 m_C是私有許可權 } };

2、protected繼承 子類可以訪問父類中的公共成員和保護成員,不可以訪問私有成員,子類中繼承的成員的中公共成員變為保護成員。

class son2:protected Base1{
	public:
		void func(){
			m_A=10;
			m_B=10;
		}
};

3、private繼承 子類可以訪問父類中的公共成員和保護成員,不可以訪問私有成員,子類中繼承的成員的公共成員和保護成員變為私有成員,如果它也有子類成員,它的子類成員將不可以訪問父類的繼承的成員。

class son3:private Base1{
	public:
		void func(){
			m_A=10;
			m_B=10;	
		}
};

父類中的所有成員物件都會被子類繼承,只是父類中的私有成員被隱藏了。
3、繼承中的析構和建構函式
1、呼叫順序

class Base{
	public:
		Base(){
			cout<<"Base建構函式"<<endl;
		}
		~Base(){
			cout<<"Base解構函式"<<endl;
		}
};
class Son:public
Base{ public: Son(){ cout<<"Son建構函式"<<endl; } ~Son(){ cout<<"Son解構函式"<<endl; } };

結果為
在這裡插入圖片描述
顯而易見建構函式是先呼叫父類的建構函式,再呼叫子類的建構函式,解構函式是先呼叫子類的解構函式再呼叫父類的解構函式。
2、建構函式注意的地方
我們要知道,子類是不會繼承父類的建構函式的,如果父類寫了預設建構函式,那麼子類可以不寫父類的建構函式,但是如果父類寫有參建構函式或者拷貝建構函式,子類是必須重寫至少一個的,否則將會出錯。

class  square :public shape
{
	public:
		int m_a;
		int p;
		square(int i):m_a(i){p=i;}
		 int area(){
			return m_a*m_a*a;
		}
};
class  cube :public square 
{
	public:
	int m_b;
	cube(int j):square(p){m_b=j;};
	int area(){
		return m_b*m_b*b;
	}
		int volume(){
		return m_b*m_b*m_b;
	}
};

由於博主經驗尚淺所以只能寫出這樣的例子,這還是我考試時候的一個題呢。我們發現在cube類中我寫了這樣的一個建構函式 cube(int j):square(p){m_b=j;};emmm沒錯,子類就是這樣重寫父類的建構函式的即 子類類名(引數):父類類名(初始值){};
建構函式大概就是這些了。歡迎補充。
4、繼承中的同名靜態成員處理
雖然同名,但卻是在不同作用域下的區域性靜態成員,所以我們可以通過一些方法來訪問:
1、通過建立物件來訪問
對於子類可以直接 物件名. 來訪問,而訪問父類的則需要 物件名.父類類名::靜態成員名 來訪問。
2、通過類名直接訪問
我們知道靜態成員是可以通過類名來直接訪問的。
訪問子類 子類類名::靜態成員名
訪問父類 子類類名::父類類名::靜態成員名,其中第一個::代表通過類名的方式訪問,第二個::代表通過作用域訪問,即通過子類訪問父類作用域下面的靜態成員。
5、菱形繼承
菱形繼承就是兩個子類同時繼承了同一個父類,又有一個子類(我們暫且叫他孫子類)同時繼承了前兩個子類,這樣的繼承影象一個菱形。但菱形繼承可能存在一些問題,就是我可能不需要前兩個子類的所有資料,我只需要繼承兩個中間的一個就行。或者孫子類的物件同時修改了兩個子類中共有的變數,那麼編譯器是不知道修改了哪一個的(親測)。怎麼辦呢,我們利用虛繼承來解決這個問題。
虛繼承就是在繼承方式前新增virtual關鍵字。
當子類繼承父類時,會產生一個虛基類指標-vbptr,子類將繼承這個指標而不是資料,而且似乎兩個父類共用這個指標,只是父類繼承的資料的記憶體地址不一樣,指標通過偏移量找到這個資料。如果同時修改兩個資料,那麼虛基類指標將會指向最後一次修改的資料的記憶體空間,這樣就不會出現模稜兩可的錯誤。