最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++析構(gòu)函數(shù)內(nèi)部工作機(jī)制詳解

 更新時(shí)間:2023年02月27日 11:18:48   作者:北冥有魚丶丶  
析構(gòu)函數(shù)(Destructor)也是一種特殊的成員函數(shù),沒有返回值,不需要程序員顯式調(diào)用(程序員也沒法顯式調(diào)用),而是在銷毀對象時(shí)自動執(zhí)行。構(gòu)造函數(shù)的名字和類名相同,而析構(gòu)函數(shù)的名字是在類名前面加一個(gè)~符號

我們主要從三個(gè)方面來學(xué)習(xí)析構(gòu)函數(shù)的工作原理:

  • 析構(gòu)函數(shù)的內(nèi)部工作機(jī)制
  • 默認(rèn)析構(gòu)函數(shù)的內(nèi)部工作機(jī)制
  • 析構(gòu)函數(shù)的調(diào)用

1、析構(gòu)函數(shù)的內(nèi)部工作機(jī)制

眾所周知,在對象的生命周期結(jié)束時(shí)會自動調(diào)用析構(gòu)函數(shù)用于清理對象所申請的資源,那么它是如何清理的呢?

析構(gòu)函數(shù)會調(diào)用delete函數(shù)釋放對象中new出來的空間,即析構(gòu)函數(shù)通過delete函數(shù)來清理對象所申請的資源,當(dāng)然如果對象沒有申請資源,那么就無需調(diào)用delete函數(shù)

由于是new出來的對象是在堆上分配空間的,即使離開了作用域,其依然存在,我們必須在析構(gòu)函數(shù)中主動delete來釋放new出來的在堆上的空間,否則對象消亡后,離開了作用域后,指向該空間的數(shù)據(jù)成員(指針)就會消失,我們失去了對這片空間的控制權(quán),別人也無法使用這片空間,這就會造成內(nèi)存泄漏。

如果對象是new出來的,那么它就是一個(gè)堆對象,不會被 操作系統(tǒng)自動回收,需要我們手動調(diào)用delete函數(shù)釋放該堆對象,在delete函數(shù)中會先調(diào)用析構(gòu)函數(shù)釋放該對象所申請的資源,那么析構(gòu)函數(shù)如何釋放對象所申請的資源呢,就是前面所說的,析構(gòu)函數(shù)又會調(diào)用delete函數(shù)來釋放對象所申請的資源,當(dāng)然如果對象沒有申請資源,那么就無需調(diào)用delete函數(shù)。

#include <iostream>
using namespace std;
class Person {
public:
    Person() {
        cout <<  "調(diào)用了Person的構(gòu)造函數(shù)" << endl;
    }
    ~Person() {
        cout << "調(diào)用了Person的析構(gòu)函數(shù)" << endl;
    }
private:
    int name;
};
int main() {
    Person* person = new  Person();
    delete person;
    return 0;
}

2、默認(rèn)析構(gòu)函數(shù)的內(nèi)部工作機(jī)制

我們清楚了析構(gòu)函數(shù)的內(nèi)部工作機(jī)制后,繼續(xù)思考一個(gè)問題,默認(rèn)析構(gòu)函數(shù)它的內(nèi)部是怎么工作的呢?

我們先來看看下面這段代碼

class Time
{
public:
	~Time()
	{
		cout << "~Time()" << endl;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	// 基本類型(內(nèi)置類型)
	int _year = 1970;
	int _month = 1;
	int _day = 1;
	// 自定義類型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

程序運(yùn)行結(jié)束后輸出:~Time(),在main方法中根本沒有直接創(chuàng)建Time類的對象,為什么最后會調(diào)用Time類的析構(gòu)函數(shù)?

這就涉及到默認(rèn)析構(gòu)函數(shù)的內(nèi)部工作機(jī)制了。

默認(rèn)析構(gòu)函數(shù),對于基本類型成員不做處理,對于自定義類型成員會去調(diào)用它的析構(gòu)函數(shù)。

總結(jié): 默認(rèn)構(gòu)造函數(shù)對基本類型不做處理,對自定義類型會調(diào)用它的默認(rèn)構(gòu)造函數(shù),默認(rèn)拷貝構(gòu)造函數(shù)對基本類型是按照字節(jié)方式直接拷貝的,對自定義類型是調(diào)用其拷貝構(gòu)造函數(shù)完成拷貝的,默認(rèn)析構(gòu)函數(shù)對基本類型不做處理,對自定義類型會調(diào)用它的析構(gòu)函數(shù)。默認(rèn)賦值運(yùn)算符對基本類型成員變量以值的方式逐字節(jié)拷貝。而對自定義類型成員變量需要調(diào)用對應(yīng)類的賦值運(yùn)算符重載完成賦值。

默認(rèn)構(gòu)造函數(shù)只有一個(gè),析構(gòu)函數(shù)只有一個(gè),拷貝構(gòu)造函數(shù)只有一個(gè),賦值運(yùn)算符重載只有一個(gè)

如果類中沒有申請資源時(shí),析構(gòu)函數(shù)可以不寫,直接使用編譯器生成的默認(rèn)析構(gòu)函數(shù),什么事都不會干,比如Date類;有資源申請時(shí),一定要寫,否則會造成資源泄漏

3、析構(gòu)函數(shù)的調(diào)用

析構(gòu)函數(shù)在對象消亡時(shí)被調(diào)用,以清理對象所申請的資源,那具體它在何時(shí)被調(diào)用呢?

析構(gòu)函數(shù)主要在以下4種情況下會被調(diào)用:

對象生命周期結(jié)束,此時(shí)會自動調(diào)用析構(gòu)函數(shù)。

#include<iostream>
using namespace std;
class Person {
public:
    Person() {
        cout << "調(diào)用了Person的構(gòu)造函數(shù)" << endl;
    }
    ~Person() {
        cout << "調(diào)用了Person的析構(gòu)函數(shù)" << endl;
    }
private:
    int name;
};
int main() {
    Person person;
    return 0;
}

運(yùn)行結(jié)果如下圖所示:

該運(yùn)行結(jié)果說明,在對象的生命周期結(jié)束后,會自動調(diào)用對象的析構(gòu)函數(shù)。

成員關(guān)系:對象car是對象person的成員,person的析構(gòu)函數(shù)被調(diào)用時(shí),對象car的析構(gòu)函數(shù)也被調(diào)用。

#include <iostream>
using namespace std;
class Car {
public:
    Car() {
        cout << "調(diào)用了Car的構(gòu)造函數(shù)" << endl;
    }
    ~Car() {
        cout << "調(diào)用了Car的析構(gòu)函數(shù)" << endl;
    }
private:
    int name;
};
class Person {
public:
    Person() {
        cout << "調(diào)用了Person的構(gòu)造函數(shù)" << endl;
    }
    ~Person() {
        cout << "調(diào)用了Person的析構(gòu)函數(shù)" << endl;
    }
private:
    int name;
    Car car;
};
int main() {
    Person person;
    return 0;
}

先調(diào)用的是包含類的析構(gòu)函數(shù),然后調(diào)用的是成員對象的析構(gòu)函數(shù)

繼承關(guān)系:當(dāng)Person是Student的父類,調(diào)用Student的析構(gòu)函數(shù),會調(diào)用Person的析構(gòu)函數(shù)。

#include <iostream>
using namespace std;
class Person {
public:
    Person() {
        cout << "調(diào)用了Person的構(gòu)造函數(shù)" << endl;
    }
    ~Person() {
        cout << "調(diào)用了Person的析構(gòu)函數(shù)" << endl;
    }
private:
    int name;
};
class Student :public Person {
public:
    Student() {
        cout << "調(diào)用了Student的構(gòu)造函數(shù)" << endl;
    }
    ~Student() {
        cout << "調(diào)用了Student的析構(gòu)函數(shù)" << endl;
    }
private:
    int name;
    string no;
};
int main() {
    Student student;
    return 0;
}

先調(diào)用的是派生類的析構(gòu)函數(shù)釋放派生類的資源,然后調(diào)用的才是父類的析構(gòu)函數(shù)釋放父類成員所指向的資源

值得注意的是,如果派生類對象是new出來的對象,基類指針指向一個(gè)new生成的派生對象,通過delete銷毀基類指針指向的派生類對象時(shí),有以下兩種情況:

1、 如果基類析構(gòu)函數(shù)不是虛析構(gòu)函數(shù),則只會調(diào)用基類的析構(gòu)函數(shù),派生類的析構(gòu)函數(shù)不被調(diào)用,此時(shí)派生類中申請的資源不被回收。

2、 如果基類析構(gòu)函數(shù)為虛析構(gòu)函數(shù),則釋放基類指針指向的對象時(shí)會調(diào)用基類及派生類析構(gòu)函數(shù),派生類對象中的所有資源被回收。

到此這篇關(guān)于C++析構(gòu)函數(shù)內(nèi)部工作機(jī)制詳解的文章就介紹到這了,更多相關(guān)C++析構(gòu)函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • cmake 學(xué)習(xí)筆記

    cmake 學(xué)習(xí)筆記

    這篇文章主要介紹了作者學(xué)習(xí)cmake 的相關(guān)資料與心得,有需要的小伙伴可以參考下
    2017-07-07
  • opencv檢測直線方法之形態(tài)學(xué)方法

    opencv檢測直線方法之形態(tài)學(xué)方法

    這篇文章主要為大家詳細(xì)介紹了opencv檢測直線方法之形態(tài)學(xué)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • C++ com編程學(xué)習(xí)詳解

    C++ com編程學(xué)習(xí)詳解

    這篇文章主要介紹了C++ COM編程的學(xué)習(xí)過程,在C++中,可以使用抽象基類來實(shí)現(xiàn)COM接口,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09
  • windows 下C++生成Dump調(diào)試文件與分析

    windows 下C++生成Dump調(diào)試文件與分析

    dump文件是C++程序發(fā)生異常時(shí),保存當(dāng)時(shí)程序運(yùn)行狀態(tài)的文件,是調(diào)試異常程序重要的方法,所以程序崩潰時(shí),除了日志文件,dump文件便成了我們查找錯(cuò)誤的最后一根救命的稻草,這篇文章主要介紹了windows 下C++生成Dump調(diào)試文件與分析,需要的朋友可以參考下
    2023-04-04
  • 詳解C語言內(nèi)核字符串拷貝與比較

    詳解C語言內(nèi)核字符串拷貝與比較

    本文將探索一下字符串的拷貝與比較,與應(yīng)用層不同內(nèi)核字符串拷貝與比較也需要使用內(nèi)核專用的API函數(shù),字符串的拷貝往往伴隨有內(nèi)核內(nèi)存分配,我們將首先簡單介紹內(nèi)核如何分配堆空間,然后再以此為契機(jī)簡介字符串的拷貝與比較
    2022-09-09
  • C++語言基礎(chǔ) 命名空間

    C++語言基礎(chǔ) 命名空間

    一個(gè)中大型軟件往往由多名程序員共同開發(fā),會使用大量的變量和函數(shù),當(dāng)有兩個(gè)人都同時(shí)定義了一個(gè)名字相同的全局變量或函數(shù)的時(shí)候,若是把他們的代碼整合在一塊編譯,此時(shí)編譯器就會提示變量或函數(shù)重復(fù)定義,C++為了解決這個(gè)問題,便引用了命名空間(namespace)的概念
    2020-01-01
  • C語言中const和define的區(qū)別你了解嘛

    C語言中const和define的區(qū)別你了解嘛

    這篇文章主要為大家詳細(xì)介紹了C語言中const和define的區(qū)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 淺析iterator與指針的區(qū)別

    淺析iterator與指針的區(qū)別

    指針和iterator都支持減法運(yùn)算,指針-指針得到的是兩個(gè)指針之間的距離,迭代器-迭代器得到的是兩個(gè)迭代器之間的距離
    2013-10-10
  • C++學(xué)習(xí)小結(jié)之語句

    C++學(xué)習(xí)小結(jié)之語句

    本文給大家匯總介紹了下C++中比較基礎(chǔ)的知識--語句,常用的語句都有詳細(xì)介紹和附上了相關(guān)示例,十分實(shí)用,有需要的小伙伴可以參考下
    2015-07-07
  • C++設(shè)置系統(tǒng)時(shí)間及系統(tǒng)時(shí)間網(wǎng)絡(luò)更新的方法

    C++設(shè)置系統(tǒng)時(shí)間及系統(tǒng)時(shí)間網(wǎng)絡(luò)更新的方法

    這篇文章主要介紹了C++設(shè)置系統(tǒng)時(shí)間及系統(tǒng)時(shí)間網(wǎng)絡(luò)更新的方法,涉及網(wǎng)絡(luò)程序設(shè)計(jì)與系統(tǒng)函數(shù)的使用,需要的朋友可以參考下
    2014-10-10

最新評論

都兰县| 徐水县| 万源市| 利川市| 平山县| 缙云县| 清丰县| 阳春市| 察雅县| 汉阴县| 运城市| 报价| 东丰县| 阿拉善左旗| 双鸭山市| 渑池县| 莆田市| 夏津县| 丹阳市| 高淳县| 乌兰浩特市| 克山县| 岚皋县| 钟祥市| 锡林浩特市| 奎屯市| 新丰县| 鄂伦春自治旗| 樟树市| 文化| 广水市| 寿阳县| 黄平县| 固阳县| 旬阳县| 岱山县| 犍为县| 胶州市| 江油市| 东丽区| 河南省|