淺談C++析構函數

C++析構前言                                                                                                         

析構函數在什麼時候會自動被調用,在什麼時候需要手動來調用,真不好意思說偶學過C++…

今日特此撥亂反正

 

C++析構誤解正文                                                                                                  

對象在構造的時候系統會分配內存資源,對一些數據成員進行初始化或者賦值;一個良好的

class需要有資源回收的機制,而這一操作便落在了析構函數的頭上,析構函數來負責類內的

資源的free。來看一段代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class myclass
{
    public:
    myclass()
    {
        cout <<"構造函數"<< endl;
    }
    ~myclass()
    {
        cout <<"析構函數"<< endl;
    }
};
  
int main()
{
    myclass mc;
    return0;
}

執行結果:

圖1

 

在main主函數當中,如果直接聲明一個對象,在聲明的時候,直接就調用了類內的構造函數,

在主函數結束之前的那一小刻,也自動調用了這個類的析構函數;在看一段代碼:

1
2
3
4
5
int main()
{
    myclass * mc;
    return0;
}

 執行結果:

 

在main主函數當中,如果直接聲明一個對象指針(只是聲明而已),既不自動調用構造函數

和析構函數。但是將main函數改爲下面:

1
2
3
4
5
6
int main()
{
    myclass * mc;
    mc =newmyclass();
    return0;
}

執行結果:

 

這裏不僅聲明瞭一個對象指針,而且new了,這說明給這一對象指針分配一個內存空間,當

這就會調用構造函數了;咦,奇怪了,爲什麼不自動調用析構函數了,說明C++內部缺少

這一機制,C++毫不客氣的對你說:“你提醒我給一個對象分配空間,那也得麻煩你提醒我

將它釋放(delete)。於是便有:

1
2
3
4
5
6
7
int main()
{
    myclass * mc;
    mc =newmyclass();
    deletemc;
    return0;
}

執行結果:

圖1

所以如果是指針在new之後需要手動釋放資源。在較大型的工程當中,資源的釋放很重要,

爲涉及的數據量比較多,稍有不慎,就會造成資源的浪費和泄露之類的問題,從現在起

你就應該養成把握資源的好習慣。


條款20:寧以pass-by-reference-to-const替換pass-by-value。——Scott Meyers

爲什麼要在這裏說在函數當中使用“常引用”,固然它跟析構函數有很大的牽連。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class myclass
{
    public:
    myclass()
    {
        cout <<"構造函數"<< endl;
    }
    ~myclass()
    {
        cout <<"析構函數"<< endl;
    }
};
  
void function(myclass mc)
{
}
  
int main()
{
    myclass mc;
    function(mc);
    return0;
}

執行結果:

 

結果很明朗,function函數內對myclass類的對象mc作了一次複製(淺複製而已)而造出了另

個對象,也就是函數內的對象副本;調用函數的時候,如果選擇是傳值調用,那麼會有參

數副本被複制到函數的棧區。

因爲這裏調用的myclass類默認的copy構造函數,而不是調用上面myclass類的構造函數,但

們都明白,無論是哪種,都了構造,都是需要花費時間的,先不管時間有多短;遇上析構

函數那是必然的。再者,如果myclass類有n個父類,而它的父類又有幾個參數需要構造析構,

最後還需要層層析構(virtual析構函數《C++虛函數和純虛函數(1)》)......那這個花費的時

間可就不能四捨五入啦。

解決方法就是寧以pass-by-reference-to-const替換pass-by-value。我們這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class myclass
{
    public:
    myclass()
    {
        cout <<"構造函數"<< endl;
    }
    ~myclass()
    {
        cout <<"析構函數"<< endl;
    }
};
  
void function(const myclass &mc)
{
}
  
int main()
{
    myclass mc;
    function(mc);
    return0;
}

結果讓我們大吃一驚:

這就是我們想要,而如果你怕function函數內會對mc做一些非法的事情,const可以把他拒之門外。

 

轉自:http://www.cnblogs.com/daoluanxiaozi/archive/2011/12/09/2281796.html

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