前面已經總結過類中的預設的成員函式:
類中的預設的成員函式
所以,既然是預設,就代表如果我們不顯示定義,編譯器就會預設生成,那麼在繼承體系中,派生類的預設成員函式又是什麼yang的呢
派生類的建構函式必須呼叫基類的建構函式初始化基類的那一部分成員
。如果基類沒有預設的建構函式,則必須在派生類建構函式的初始化列表階段顯示呼叫。( 一旦基類顯示定義非預設(非全預設)的建構函式,編譯器將不再自動呼叫,需要使用者在派生類的初始化列表中顯示呼叫基類的建構函式。而如果基類沒有顯示定義建構函式,子類可以不用定義,讓編譯器直接呼叫基類的預設建構函式即可)
派生類的拷貝建構函式必須呼叫基類的拷貝構造完成基類的拷貝初始
化。派生類的operator=必須要呼叫基類的operator=完成基類的複製
。
(對於2和3兩條,如果繼承體系中不涉及資源管理問題,使用者可以不用顯示提供,但是一旦涉及資源管理問題,就必須顯示提供,否則就很容易發生淺拷貝問題,從而導致資源洩漏)派
生類的析構函式會在被呼叫完成後自動呼叫基類的析構函式清理基類成
員。因為這樣才能保證派生類物件先清理派生類成員再清理基類成員的順序。派生類物件初始化先呼叫基類構造再調派生類構
造。派生類物件析構清理先呼叫派生類析構再調基類的析構
**:
class
person
person
(const person& p)
:_name
(p._name)
person&
operator=(
const person& p )
~person()
protected
: string _name ;
// 姓名};
class
student
:public person
student
(const student& s)
:person
(s),
_num
(s ._num)
student&
operator=(
const student& s )
return
*this;}
~student()
protected
:int _num ;
//學號};
即先執行基類的構造--->子類的構造--->派生類行為--->派生類的析構--->基類析構
。
先呼叫派生類的構造--->在派生類的建構函式的初始化列表位置呼叫基類的構造--->派生類的行為--->派生類的析構--->基類析構
。
所以從不同的角度看到的執行順序是不一樣的,需要注意
class
student
;class
person
;class
student
:public person
;void
display
(const person& p,
const student& s)
void
main()
class
person
protected
: string _name ;
// 姓名
public
:static
int _count;
// 統計人的個數。};
int person :: _count =0;
class
student
:public person
;class
graduate
:public student
;void
testperson()
C 中的繼承(二)
一 基本概念 1 類的繼承,是新的類從已有類那裡得到已有的特性。或從已有類產生新類的過程就是類的派生。原有的類稱為基類或父類,產生的新類稱為派生類或子類。2 派生類的宣告 class 派生類名 繼承方式 基類名1,繼承方式 基類名2,繼承方式 基類名n 3 乙個派生類可以同時有多個基類,這種情況稱為...
c 繼承 二 菱形繼承
在c 一 中,寫的程式是單繼承 即乙個子類只有乙個父類 下面將寫乙個多繼承程式 即乙個子類有兩個或兩個以上的父類 多繼承是c 的乙個缺陷 對上述 直接進行編譯會產生問題,問題在於dd.fun 編譯器報錯很明確,它不知道這裡的fun函式是要訪問b中的還是c中的。解決這個問題有兩種方案,第一種是重寫,即...
C 繼承中的二義性
當乙個類有多個基類的時候,通過所有直接基類同時進行名字查詢。多重繼承的派生類有可能從兩個或多個基類繼承同名成員,對該成員如果不加限定的話,這樣使用就是二義性的。即使兩個繼承的函式有不同的形參表也會產生錯誤,類似的,即使函式在乙個類中是私有的而在另乙個類中是公用的或受保護的,也同樣是錯誤的。名字查詢總...