C++知識點隨筆(四):耦合問題、new和malloc、虛析構、多繼承

一、耦合問題

即互相包含頭文件的問題,解決方法:
1. 在一個類的頭文件裏聲明另一個類,那麼我們在定義的時候就不能new對象,但是可以定義一個指針。這只是爲了保證編譯通過,等到具體創建對象的時候還是會使用原來的類成員。
2. 可以抽象出一個父類,讓這個父類裏面同時包含這兩個子類裏需要耦合的部分。
3. friend方法,其實也相當於一個聲明,但是friend會破壞類的封裝性。(傳說中友元是不需要頭文件的)。
4. 降低耦合性參考:http://developer.178.com/200912/54167815997.html

二、new和malloc的區別

malloc只是在堆區申請空間;
而new裏面封裝了三件事情:
1. 調用類的構造函數
2. 在堆區申請空間
3. 返回對象的首地址

delete封裝了兩件事:
1. 調用析構函數
2. 刪除指針所指向的全部空間
注意:delete刪除空間時一定將new的對象大小全部刪除了,但是調用誰的析構就要看這個指針本身的類型了。所以當這種情況時:

CFather *son = new CSon;
delete son;

就不會調用子類的析構函數,從而可能會造成內存泄露。所以要解決這個問題,就有了我們後面的虛析構的誕生。

三、虛析構

虛析構就是當我們delete父類指針的時候,會首先調用子類的析構函數,然後再調用父類的析構函數,這樣就保證了所有的子類析構函數都可以調用,從而避免了內存泄露的問題。它的形式是這樣的:

virtual ~CFather();

什麼時候用虛析構呢?
有多態或者說有virtual的時候就用虛析構。這個虛析構同樣也存在於虛函數列表中,子類的析構函數會重寫這個表中的虛析構函數指針。注意:虛析構函數指針不一定就在虛函數列表的最後,它和普通虛函數一樣,是根據父類中聲明的順序加入虛函數列表的。

爲什麼調用子類的析構函數之後一定會調用父類的析構函數?
我們之前講過,子類繼承父類的過程其實相當於在最開始的時候定義了一個父類的對象,那麼當我們執行完子類的析構函數之後,這個子類就要回收了,所以定義的父類的對象的作用域也就結束了,就會自動調用父類對象的析構函數了。

四、多繼承

多繼承形式:

class AA : public BB, public CC

多繼承的構造順序是:BB->CC->AA
多繼承的所以父類中,從左向右依次執行構造函數。
多繼承的缺點:
多繼承會出現訪問不明確的問題,因爲多繼承是這樣的:
這裏寫圖片描述
所以有兩份AA,這樣我們在使用AA的成員變量的時候就會發生訪問不明確的問題,解決的方法就是使用虛繼承,這個我們後面再講。
另外當我們多繼承的父類,即BB和CC同時擁有兩個同名的虛函數時,子類也無法將他們重寫,還是指向不明確的問題,這個問題我們可以通過嵌套類來解決,後面再講。
其實多繼承的出現本身就是一種缺陷,證明了我們的程序設計的不夠完美,所以我們在程序設計的時候儘量避免多繼承的出現。

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