欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++面向?qū)ο缶幊讨鰳?gòu)詳解

 更新時(shí)間:2022年03月17日 10:27:14   作者:charlee44  
這篇文章主要為大家詳細(xì)介紹了C++面向?qū)ο缶幊讨鰳?gòu),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

1. 概述

類的析構(gòu)函數(shù)執(zhí)行與構(gòu)造函數(shù)相反的操作,當(dāng)對(duì)象結(jié)束其生命周期,程序就會(huì)自動(dòng)執(zhí)行析構(gòu)函數(shù):

class ImageEx
{
public:
    ImageEx()
    {
        cout << "Execute the constructor!" << endl;
    }
    ~ImageEx()
    {
        cout << "Execute the destructor!" << endl;
    }
};
int main()
{
    ImageEx imageEx;
    return 0;
}

那么同樣的問(wèn)題來(lái)了,為什么要有析構(gòu)函數(shù)呢?

2. 詳論

2.1. 對(duì)象生命周期

在經(jīng)典C++中,需要通過(guò)new/delete來(lái)手動(dòng)管理動(dòng)態(tài)內(nèi)存。如果我們?cè)陬愔猩暾?qǐng)一個(gè)動(dòng)態(tài)數(shù)組,并且通過(guò)自定義的函數(shù)Release()來(lái)釋放它:

class ImageEx
{
public:
    ImageEx()
    {
        cout << "Execute the constructor!" << endl;
        data = new unsigned char[10];
    }
    ~ImageEx()
    {
        cout << "Execute the destructor!" << endl;
    }
    void Release()
    {
        delete[] data;
        data = nullptr;
    }
private:
    unsigned char * data;
};
int main()
{
    {
        ImageEx imageEx;
        imageEx.Release();
    }
    return 0;
}

那么,當(dāng)類對(duì)象離開(kāi)作用域,結(jié)束生命周期之前,就必須顯示調(diào)用一次成員函數(shù)Release(),否則就會(huì)造成內(nèi)存泄漏:對(duì)象在調(diào)用析構(gòu)函數(shù)之后,只會(huì)銷毀數(shù)據(jù)成員data本身,而不是其指向的內(nèi)存。

那么,一個(gè)合理的實(shí)現(xiàn)是,將成員函數(shù)Release()放入到析構(gòu)函數(shù):

class ImageEx
{
public:
    ImageEx()
    {
        cout << "Execute the constructor!" << endl;
        data = new unsigned char[10];
    }
    ~ImageEx()
    {
        Release();
        cout << "Execute the destructor!" << endl;
    }
private:
    unsigned char * data;
    void Release()
    {
        delete[] data;
        data = nullptr;
    }
};
int main()
{
    {
        ImageEx imageEx;       
    }
    return 0;
}

這樣,當(dāng)類對(duì)象離開(kāi)作用域,結(jié)束生命周期之前,就自動(dòng)通過(guò)析構(gòu)函數(shù),實(shí)現(xiàn)了動(dòng)態(tài)數(shù)組的釋放。好處是顯而易見(jiàn)的:實(shí)現(xiàn)了類似于內(nèi)置數(shù)據(jù)類型對(duì)象的生命周期管理,我們可以像使用內(nèi)置數(shù)據(jù)類型對(duì)象一樣使用類對(duì)象。

2.2. 不一定需要顯式析構(gòu)

在一些現(xiàn)代高級(jí)編程語(yǔ)言(C#、Java、Javascript)中,已經(jīng)不用去手動(dòng)管理動(dòng)態(tài)內(nèi)存,取而代之的,是其與操作系統(tǒng)的中間件(.net,jvm,瀏覽器)的GC(垃圾回收)機(jī)制。而在現(xiàn)代C++中,提倡通過(guò)智能指針(std::shared_ptr、std::unique_ptr、std::weak_ptr)來(lái)管理動(dòng)態(tài)內(nèi)存;對(duì)于動(dòng)態(tài)數(shù)組,則使用標(biāo)準(zhǔn)容器std::vector則更好。在兩者的內(nèi)部都實(shí)現(xiàn)了前文提到的對(duì)象生命周期管理,在離開(kāi)作用域后,通過(guò)析構(gòu)函數(shù)自動(dòng)釋放管理的內(nèi)存,無(wú)需再手動(dòng)進(jìn)行回收。

那么,一個(gè)顯而易見(jiàn)的推論就出來(lái)了,如果我們?cè)陬愔惺褂弥悄苤羔樆蛘遶ector容器來(lái)替代new/delete管理動(dòng)態(tài)內(nèi)存,是不是就可以不用析構(gòu)函數(shù)了?嚴(yán)格來(lái)說(shuō),是不用顯式使用析構(gòu)函數(shù):

class ImageEx
{
public:
    ImageEx():
        data(10)
    {
        cout << "Execute the constructor!" << endl;        
    }
private:
    std::vector<unsigned char> data;
};
int main()
{
    ImageEx imageEx;      
    return 0;
}

實(shí)際上,并不是這個(gè)類不存在析構(gòu)函數(shù),而是編譯器會(huì)為它生成一個(gè)合成的析構(gòu)函數(shù),在這個(gè)析構(gòu)函數(shù)體中,什么也不用做。因?yàn)轭愔械膭?dòng)態(tài)內(nèi)存,已經(jīng)交由std::vector容器來(lái)管理。當(dāng)類對(duì)象離開(kāi)作用域調(diào)用析構(gòu)函數(shù)之后,會(huì)銷毀這個(gè)std::vector容器數(shù)據(jù)成員,進(jìn)而觸發(fā)其析構(gòu)函數(shù),釋放其管理的內(nèi)存。

2.3. 析構(gòu)的必要性

根據(jù)上一節(jié)內(nèi)容,不一定需要顯式析構(gòu)。因?yàn)楝F(xiàn)代C++的一些機(jī)制能夠幫你自動(dòng)管理動(dòng)態(tài)內(nèi)存。但是析構(gòu)函數(shù)還是必要的,這是由于C++語(yǔ)言本身的性質(zhì)決定的。作為C語(yǔ)言大部分內(nèi)容的超集,需要兼容C語(yǔ)言手動(dòng)管理內(nèi)存的特性。更重要的是,現(xiàn)代操作系統(tǒng)幾乎全部由C語(yǔ)言編寫,與底層的交互不可避免的需要手動(dòng)使用動(dòng)態(tài)內(nèi)存管理。

3. 總結(jié)

所以我們就能理解了,C++這門語(yǔ)言的設(shè)計(jì)哲學(xué)就是就是這樣:既想要C語(yǔ)言的高性能,也想要高級(jí)語(yǔ)言高度抽象的特性。如果我們必須兼容C語(yǔ)言底層設(shè)計(jì),那我們最好使用析構(gòu)函數(shù)釋放動(dòng)態(tài)內(nèi)存;否則多數(shù)情況下,我們應(yīng)該使用智能指針或者stl容器來(lái)管理動(dòng)態(tài)內(nèi)存,從而避免顯示使用析構(gòu)函數(shù)。

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!     

相關(guān)文章

  • C語(yǔ)言kmp算法簡(jiǎn)單示例和實(shí)現(xiàn)原理探究

    C語(yǔ)言kmp算法簡(jiǎn)單示例和實(shí)現(xiàn)原理探究

    這篇文章主要介紹了C語(yǔ)言kmp算法簡(jiǎn)單示例和實(shí)現(xiàn)原理探究,本文用簡(jiǎn)潔的語(yǔ)言說(shuō)明KMP算法的原理,并給出了示例,需要的朋友可以參考下
    2014-09-09
  • C++?實(shí)現(xiàn)單鏈表創(chuàng)建、插入和刪除

    C++?實(shí)現(xiàn)單鏈表創(chuàng)建、插入和刪除

    這篇文章主要介紹了C++?實(shí)現(xiàn)單鏈表創(chuàng)建、插入和刪除方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • c++ 解析yaml文件的步驟

    c++ 解析yaml文件的步驟

    這篇文章主要介紹了c++ 解析yaml文件的步驟,幫助大家更好的理解和使用c++,感興趣的朋友可以了解下
    2020-12-12
  • Qt學(xué)習(xí)之QListWidget控件的使用教程詳解

    Qt學(xué)習(xí)之QListWidget控件的使用教程詳解

    這篇文章主要為大家詳細(xì)介紹了Qt中QListWidget控件的使用教程,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定的幫助,需要的可以參考一下
    2022-12-12
  • C語(yǔ)言二叉樹(shù)常見(jiàn)操作詳解【前序,中序,后序,層次遍歷及非遞歸查找,統(tǒng)計(jì)個(gè)數(shù),比較,求深度】

    C語(yǔ)言二叉樹(shù)常見(jiàn)操作詳解【前序,中序,后序,層次遍歷及非遞歸查找,統(tǒng)計(jì)個(gè)數(shù),比較,求深度】

    這篇文章主要介紹了C語(yǔ)言二叉樹(shù)常見(jiàn)操作,結(jié)合實(shí)例形式詳細(xì)分析了基于C語(yǔ)言的二叉樹(shù)前序,中序,后序,層次遍歷及非遞歸查找,統(tǒng)計(jì)個(gè)數(shù),比較,求深度等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-04-04
  • C++第三方日志庫(kù)log4cplus的安裝與使用配置教程

    C++第三方日志庫(kù)log4cplus的安裝與使用配置教程

    log4cplus是C++編寫的開(kāi)源的日志系統(tǒng),log4cplus具有線程安全、靈活、以及多粒度控制的特點(diǎn),本文給大家介紹C++第三方日志庫(kù)log4cplus的安裝與使用教程,感興趣的朋友一起看看吧
    2022-02-02
  • C++中函數(shù)匹配機(jī)制詳解

    C++中函數(shù)匹配機(jī)制詳解

    大家好,本篇文章主要講的是C++中函數(shù)匹配機(jī)制詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • C語(yǔ)言實(shí)現(xiàn)加密解密功能

    C語(yǔ)言實(shí)現(xiàn)加密解密功能

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)加密解密功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C++ 自增、自減運(yùn)算符的重載和性能分析小結(jié)

    C++ 自增、自減運(yùn)算符的重載和性能分析小結(jié)

    這篇文章主要介紹了C++ 自增、自減運(yùn)算符的重載和性能分析小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • C++超詳細(xì)講解RTTI和cast運(yùn)算符的使用

    C++超詳細(xì)講解RTTI和cast運(yùn)算符的使用

    RTTI(Runtime Type Identification)是“運(yùn)行時(shí)類型識(shí)別”的意思。C++引入這個(gè)機(jī)制是為了讓程序在運(yùn)行時(shí)能根據(jù)基類的指針或引用來(lái)獲得該指針或引用所指的對(duì)象的實(shí)際類型,cast強(qiáng)制轉(zhuǎn)換運(yùn)算符是一種特殊的運(yùn)算符,它把一種數(shù)據(jù)類型轉(zhuǎn)換為另一種數(shù)據(jù)類型
    2022-08-08

最新評(píng)論