c++物件導向類和類的關係可以分為3類:復合(composition)、委託(delegation)、繼承(inheritance)。
這裡**當類中有復合類時,復合類和本類的構/析構函式執行順序, 或者繼承時,子類和父類建構函式執行順序,或者繼承時子類有復合類、或基類有復合類時又該如何執行。
只要記住這句話就可以:構造順序由內而外,析構順序由外而內。
由於析構和構造順序相反,所以下面程式均不示範析構函式。
下面示例4個程式:
(1)類中有復合類時
(2)繼承
(3)繼承時,子類有復合類
(4)繼承時,父類有復合類
復合可以用uml圖表示如下:
繼承表示如下:
輸出結果:
c has constructed
a has constructed
分析:建構函式是由內而外,當a中有c時,則可以表示如下:
從圖中可以看到,a中包含c,則c是內部,a是外部。
結論:當類中有復合類c時,本類a建構函式在執行前先執行復合類的預設建構函式,且此執行是編譯器自動執行的。
為什麼要說是復合類的預設建構函式,如果復合類c沒有預設建構函式,會發生什麼?編譯器直接告訴你a中的c沒有預設建構函式。那怎麼辦呢,這時候就要顯示呼叫c的建構函式了。
// 沒有顯示呼叫c的建構函式
class c
};class a
c c;
};int main()
// 顯示呼叫c的建構函式
class c
};class a
c c;
};int main()
結果顯示:
c has constructed
a has constructed
class a
};class b : public a
};int main()
結果顯示:
a has constructed
b has constructed
分析:建構函式是由內而外,當b繼承a時,則可以表示如下:
結論:繼承時,先執行父類a的預設建構函式,然後執行本類b的建構函式,a的預設建構函式是編譯器自動執行的。
為什麼要說是復合類的預設建構函式,如果父類a沒有預設建構函式,會發生什麼?編譯器直接告訴你a中的c沒有預設建構函式。那怎麼辦呢,這時候就要顯示呼叫a的建構函式了。(下面程式就不示範錯誤情況了,直接示範如何顯示呼叫)
class a
};class b : public a
};int main()
結果顯示:
a has constructed
b has constructed
class c
};class a
};class b : public a
c c;
};int main()
結果顯示:
a has constructed
c has constructed
b has constructed
分析:建構函式是由內而外,當b繼承a時,且子類b為有c復合類時,則可以表示如下:
結論:繼承時且子類b中有復合類c時,先執行父類a的預設建構函式,然後執行復合類c的建構函式,最後執行本類b的建構函式,a和c的預設建構函式都是編譯器自動執行的。
class c
};class a
c c;
};class b : public a
};int main()
結果顯示:
c has constructed
a has constructed
b has constructed
分析:建構函式是由內而外,當b繼承a時,且父類a為有c復合類時,則可以表示如下:
結論:繼承時且父類中有c時,先執行父類a中的c的的預設建構函式,然後執行a的建構函式,最後執行本類b的建構函式,a和c的預設建構函式都是編譯器自動執行的。
建構函式 函式過載 復合類 析構函式
建構函式特點 注意 如果不標明public裡面的,程式預設為私有成員變數 預設建構函式分兩種 1.建構函式不帶引數 2.建構函式帶引數但引數都有預設值 eg circle 預設建構函式 circle float a 0,float b 0,float c 0 預設建構函式帶引數有預設值 circle...
繼承中的構造和析構函式
子類物件在建立時首先會呼叫父類的建構函式,在父類的建構函式執行結束後,再執行子類的建構函式。當父類的建構函式有引數時,需要在子類的初始化列表中顯示呼叫。析構函式的呼叫的先後順序與建構函式相反 結論 建構函式 先呼叫父類 再呼叫子類 析構函式 先呼叫子類 再呼叫父類 如下所示 include usin...
繼承和建構函式析構函式呼叫順序
繼承 的重用性 using namespace std 人類 class human protected char name int age 男人 class man public human private 兄弟 char brother void work human h void main 向...