對於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,子類將繼承這個指標而不是資料,而且似乎兩個父類共用這個指標,只是父類繼承的資料的記憶體地址不一樣,指標通過偏移量找到這個資料。如果同時修改兩個資料,那麼虛基類指標將會指向最後一次修改的資料的記憶體空間,這樣就不會出現模稜兩可的錯誤。