成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

C++面向?qū)ο竽嫦蚬P記-創(chuàng)新互聯(lián)

筆記參考自黃色那本C++逆向揭秘

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比長豐網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式長豐網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋長豐地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
對(duì)象的識(shí)別 所有的類都有構(gòu)造函數(shù)嗎
  1. 情況一:編譯器會(huì)為類內(nèi)有虛函數(shù),父類有虛函數(shù),或者本類中的對(duì)象成員有虛函數(shù)的情況下,編譯器會(huì)添加默認(rèn)的構(gòu)造函數(shù),用于完成虛表的初始化工作。
  2. 情況二:編譯器會(huì)為父類或者本類中定義的成員對(duì)象帶有構(gòu)造函數(shù)時(shí)。派生類的構(gòu)造順序是先構(gòu)造父類再構(gòu)造自身,需要添加默認(rèn)的構(gòu)造函數(shù)調(diào)用父類的構(gòu)造函數(shù)。
構(gòu)造函數(shù)的識(shí)別
  1. 該函數(shù)的調(diào)用是某對(duì)象在作用域內(nèi)的第一次成員函數(shù)的調(diào)用,通過this指針判斷是哪個(gè)對(duì)象的成員函數(shù)。
  2. 使用thiscall調(diào)用方式,使用ecx傳遞this指針
  3. 返回值為this指針,與傳入的第一個(gè)參數(shù)相同。
析構(gòu)函數(shù)的識(shí)別
  1. 該函數(shù)的調(diào)用時(shí)某對(duì)象在作用域內(nèi)的最后一次成員函數(shù)調(diào)用,通過this指針來分辨是那個(gè)對(duì)象的成員函數(shù)。
  2. 使用thiscal調(diào)用方式,使用ecx寄存器來傳遞this指針。
  3. 沒有返回值。也沒有參數(shù)
全局構(gòu)造函數(shù)和全局析構(gòu)函數(shù)的調(diào)用時(shí)機(jī)

1._cinit()函數(shù)的第二個(gè)_initterm()函數(shù)內(nèi)完成,在_initterm()中。會(huì)先執(zhí)行__onexitinit()函數(shù)初始化函數(shù)指針數(shù)組。在執(zhí)行每個(gè)全局對(duì)象構(gòu)造代理函數(shù)時(shí)都會(huì)先執(zhí)行對(duì)象的構(gòu)造函數(shù),然后使用atexit()函數(shù)注冊(cè)析構(gòu)代理函數(shù)。
2. 編譯器會(huì)為每個(gè)全局對(duì)象和靜態(tài)對(duì)象建立一個(gè)中間代理的析構(gòu)函數(shù)用于傳入全局對(duì)象的this指針。(那局部對(duì)象、參數(shù)對(duì)象和返回對(duì)象呢?)

函數(shù)調(diào)用時(shí)對(duì)象是否調(diào)用拷貝構(gòu)造函數(shù)

1.編譯器默認(rèn)采用的是淺拷貝,即所有拷貝的對(duì)象和原對(duì)象引用的是同一資源,比如指針會(huì)簡單地復(fù)制,而不是申請(qǐng)新的內(nèi)存空間,將指針?biāo)赶虻膬?nèi)容進(jìn)行拷貝然后復(fù)制。這種淺拷貝在對(duì)象退出其作用域時(shí)釋放資源可能引發(fā)錯(cuò)誤,將同一份資源重復(fù)釋放。
2.函數(shù)調(diào)用時(shí),如果以對(duì)象為參數(shù)而非對(duì)象指針或引用為參數(shù),并且返回一個(gè)對(duì)象。調(diào)用之前,棧中除了局部對(duì)象的內(nèi)存空間外,還有一份內(nèi)存空間用于保存返回對(duì)象。調(diào)用函數(shù)之后在該棧幀中生成一個(gè)對(duì)象,退出函數(shù)時(shí),該對(duì)象會(huì)被拷貝到返回對(duì)象中,最后回到調(diào)用者的棧幀后,再將該對(duì)象拷貝到引用該對(duì)象的變量中。
3. 設(shè)置了返回對(duì)象的原因是,如果調(diào)用者的作用域某變量要引用被調(diào)用函數(shù)中的對(duì)象,而此時(shí)已經(jīng)退出該函數(shù)棧幀,即退出了該局部變量的作用域。棧中的數(shù)據(jù)(包括作為參數(shù)傳入的返回對(duì)象的地址)可能被覆蓋從而產(chǎn)生錯(cuò)誤,所以需要在調(diào)用者的棧幀中用一塊內(nèi)存空間保存返回對(duì)象和臨時(shí)對(duì)象,將返回對(duì)象拷貝到臨時(shí)對(duì)象中,方便后續(xù)的引用。拷貝順序:被調(diào)用者中的對(duì)象–>返回對(duì)象–>臨時(shí)對(duì)象–>調(diào)用者中的對(duì)象。
4. 如果使用指針作為參數(shù)和返回值,函數(shù)內(nèi)就沒有對(duì)拷貝構(gòu)造函數(shù)的調(diào)用。這也是一個(gè)判斷參數(shù)或返回值時(shí)對(duì)象還是對(duì)象指針的方法。

虛函數(shù)的識(shí)別
  1. 找到對(duì)象的虛函數(shù)表
  2. 利用IDA的交叉引用,找到引用虛函數(shù)表的位置(構(gòu)造函數(shù)和析構(gòu)函數(shù)會(huì)設(shè)置虛函數(shù)表)
  3. 根據(jù)前面的條件,判斷這些函數(shù)是否是構(gòu)造函數(shù)和析構(gòu)函數(shù)。
  4. 如果滿足條件,這說明這是一個(gè)虛函數(shù)。否則則可能是用戶自定義的函數(shù)指針數(shù)組。
對(duì)象的析構(gòu)和釋放
  1. 如果析構(gòu)函數(shù)是虛函數(shù),也會(huì)有多態(tài)行為。表現(xiàn)在匯編指令中,會(huì)發(fā)現(xiàn),調(diào)用虛表中的析構(gòu)函數(shù)前,也會(huì)重復(fù)對(duì)虛表進(jìn)行寫入。但是寫入順序與構(gòu)造函數(shù)相反,先寫入子類自身的虛表,再寫入父類的。
  2. 析構(gòu)函數(shù)釋放堆空間是兩回事。顯式調(diào)用了析構(gòu)函數(shù)不一定會(huì)釋放該對(duì)象的堆空間。通過C++的放置語法,可以在已析構(gòu)對(duì)象的對(duì)內(nèi)存中創(chuàng)建一個(gè)新的對(duì)象,從而節(jié)約內(nèi)存空間。如下:
    void main(int argc, char* argv[]){CPerson *pPerson = new CChinese;
    	pPerson->ShowSpeak();
    	pPerson->~CPerson();	//顯式調(diào)用析構(gòu)函數(shù)
    	
    	//C++放置語法:將pPerson指向的堆內(nèi)存作為CChinese類新對(duì)象的首地址,并調(diào)用其構(gòu)造函數(shù)。從而重復(fù)使用一個(gè)堆內(nèi)存。
    	pPerson = new(pPerson) CChinese();
    	delete pPerson;
    }
    在匯編指令中,會(huì)通過傳遞給析構(gòu)函數(shù)的參數(shù)判斷是否需要釋放堆空間,如果不需要,則會(huì)跳過delete的調(diào)用。
判斷繼承關(guān)系的方法
  1. 在虛表的地址處利用交叉引用功能“Chart of xrefs to”得到所有直接引用這個(gè)地址的位置。
  2. 即可得到所有構(gòu)造函數(shù)和析構(gòu)函數(shù)。
  3. 找到每一次引用的前面最后一次寫入虛表的地方。并確定函數(shù)范圍。
  4. 構(gòu)造函數(shù)中先寫入父類的虛表,再寫入子類的虛表;析構(gòu)函數(shù)中則相反。

一些函數(shù)可能被編譯器內(nèi)聯(lián),從而沒有this指針的傳遞和使用。

單繼承類與多繼承類虛表指針的區(qū)別
  1. 單繼承類在類對(duì)象占用的內(nèi)存空間中,只保存一份虛表指針,對(duì)應(yīng)一個(gè)虛表。構(gòu)造時(shí)先構(gòu)造父類函數(shù),再構(gòu)造自身,析構(gòu)時(shí)相反,都只調(diào)用一次父類的構(gòu)造函數(shù)和析構(gòu)函數(shù)。
  2. 多重繼承類保存的虛表指針的數(shù)量等于父類的個(gè)數(shù)(如果父類沒有虛函數(shù)呢?)。從子類對(duì)象轉(zhuǎn)換為父類指針時(shí),會(huì)跳轉(zhuǎn)到對(duì)象的父類部分的首地址并賦值。構(gòu)造時(shí),按照繼承列表中的順序依次調(diào)用父類的構(gòu)造函數(shù)構(gòu)造對(duì)應(yīng)的內(nèi)存部分,析構(gòu)時(shí)先析構(gòu)自身,然后按照相反順序析構(gòu)父類對(duì)象部分
  3. 當(dāng)對(duì)象作為成員時(shí),類對(duì)象的內(nèi)存結(jié)構(gòu)和多重繼承很相似。類中無虛函數(shù)時(shí),整個(gè)類對(duì)象的內(nèi)存結(jié)構(gòu)和多重繼承一樣。父類或成員對(duì)象存在虛函數(shù)時(shí),通過虛表指針的位置和構(gòu)造函數(shù)、析構(gòu)函數(shù)中填寫虛表指針的數(shù)目及目標(biāo)地址,來還原繼承貨成員關(guān)系。
    1. 假如某對(duì)象為第一個(gè)成員,且該類無虛函數(shù),那么類對(duì)象的首地址就是該成員對(duì)象的首地址,如果該成員對(duì)象有虛函數(shù),則首地址就是該成員對(duì)象的虛表指針,與多重繼承的表現(xiàn)相似;
    2. 假如某對(duì)象為第一個(gè)成員,且該類有虛函數(shù),那么類對(duì)象的首地址時(shí)該類的虛表指針,然后才是該成員對(duì)象的內(nèi)存部分的首地址。
    3. 假如對(duì)象不是定義的第一個(gè)成員,則該成員對(duì)象的偏移處才是該成員對(duì)象的成員或虛表指針,此時(shí)以該成員首地址為this指針的函數(shù),即為該成員對(duì)象的成員函數(shù)(交叉引用判斷)。
虛基類和虛繼承
  1. 虛基類也稱為抽象類。
  2. 對(duì)于純虛函數(shù),由于沒有實(shí)現(xiàn)。其函數(shù)地址指向的事void __cdecl _purecall(void),該函數(shù)中會(huì)結(jié)束程序,并發(fā)出錯(cuò)誤編碼信息0x19。Release版本中,編譯器會(huì)進(jìn)行優(yōu)化,純虛函數(shù)將會(huì)被優(yōu)化掉。
問題
  1. 子類對(duì)象構(gòu)造完成時(shí),虛表指針已經(jīng)是子類的虛表了。為什么編譯器在析構(gòu)函數(shù)中再次將虛表設(shè)置為子類的虛表?

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁標(biāo)題:C++面向?qū)ο竽嫦蚬P記-創(chuàng)新互聯(lián)
轉(zhuǎn)載注明:http://jinyejixie.com/article6/peoig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、靜態(tài)網(wǎng)站、企業(yè)建站、標(biāo)簽優(yōu)化、虛擬主機(jī)品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
南宁市| 六安市| 儋州市| 罗源县| 铜鼓县| 元江| 天峨县| 红安县| 铁力市| 三原县| 汶上县| 崇文区| 岳西县| 平果县| 区。| 平乡县| 临湘市| 兴文县| 久治县| 米泉市| 财经| 元氏县| 嘉兴市| 肥东县| 章丘市| 新建县| 如皋市| 兴隆县| 武威市| 长顺县| 寻乌县| 沧州市| 罗江县| 临海市| 定日县| 建瓯市| 读书| 通城县| 门源| 芜湖县| 宁远县|