struct與class的區(qū)別
- C的struct與C++的class的區(qū)別:struct只是作為一種復(fù)雜數(shù)據(jù)類型定義煞躬,不能用于面向?qū)ο缶幊獭?/li>
- C++中的struct和class的區(qū)別:對(duì)于成員訪問權(quán)限以及繼承方式,class中默認(rèn)的是private的骗村,而struct中則是public的。class還可以用于表示模板類型呀枢,struct則不行胚股。
定義一個(gè)空的類型,無任何成員變量和成員函數(shù)裙秋。在該類型中添加一個(gè)構(gòu)造函數(shù)和析構(gòu)函數(shù)琅拌。把析構(gòu)函數(shù)標(biāo)記為虛函數(shù)呢?一個(gè)只含有虛函數(shù)的類的size為多少
- sizeof(空類) = 1;
因?yàn)橐粋€(gè)空類也要實(shí)例化摘刑,所謂類的實(shí)例化就是在內(nèi)存中分配一塊地址进宝,每個(gè)實(shí)例在內(nèi)存中都有獨(dú)一無二的地址。同樣空類也會(huì)被實(shí)例化枷恕,所以編譯器會(huì)給空類隱含的添加一個(gè)字節(jié)党晋,這樣空類實(shí)例化之后就有了獨(dú)一無二的地址了。所以空類的sizeof為1徐块。 - 析構(gòu)函數(shù)隶校,跟構(gòu)造函數(shù)這些成員函數(shù),是跟sizeof無關(guān)的蛹锰,也不難理解因?yàn)槲覀兊膕izeof是針對(duì)實(shí)例,而普通成員函數(shù)绰疤,是針對(duì)類體的铜犬,一個(gè)類的成員函數(shù),多個(gè)實(shí)例也共用相同的函數(shù)指針,所以自然不能歸為實(shí)例的大小
- 虛函數(shù)為4癣猾,因?yàn)橛刑摵瘮?shù)表
含虛函數(shù)類的虛函數(shù)表是存放在哪里敛劝?
虛函數(shù)表是全局共享的元素,即全局僅有一個(gè).
虛函數(shù)表類似一個(gè)數(shù)組,類對(duì)象中存儲(chǔ)vptr指針,指向虛函數(shù)表.即虛函數(shù)表不是函數(shù),不是程序代碼,不肯能存儲(chǔ)在代碼段.
虛函數(shù)表存儲(chǔ)虛函數(shù)的地址,即虛函數(shù)表的元素是指向類成員函數(shù)的指針,而類中虛函數(shù)的個(gè)數(shù)在編譯時(shí)期可以確定,即虛函數(shù)表的大小可以確定,即大小是在編譯時(shí)期確定的,不必動(dòng)態(tài)分配內(nèi)存空間存儲(chǔ)虛函數(shù)表,所以不再堆中.根據(jù)以上特征,虛函數(shù)表類似于類中靜態(tài)成員變量.靜態(tài)成員變量也是全局共享,大小確定.所以虛函數(shù)表和靜態(tài)成員變量一樣,存放在全局?jǐn)?shù)據(jù)區(qū).
c/c++程序所占用的內(nèi)存一共分為五種:
棧區(qū),堆區(qū),程序代碼區(qū),全局?jǐn)?shù)據(jù)區(qū)(靜態(tài)區(qū)),文字常量區(qū).
顯而易見,虛函數(shù)表存放在全局?jǐn)?shù)據(jù)區(qū).虛函數(shù)表是class specific的,也就是針對(duì)一個(gè)類來說的纷宇,這里有點(diǎn)像一個(gè)類里面的staic成員變量夸盟,即它是屬于一個(gè)類所有對(duì)象的,不是屬于某一個(gè)對(duì)象特有的像捶,是一個(gè)類所有對(duì)象共有的上陕。
虛函數(shù)表是編譯器來選擇實(shí)現(xiàn)的,編譯器的種類不同拓春,可能實(shí)現(xiàn)方式不一樣释簿,就像前面我們說的vptr在一個(gè)對(duì)象的最前面,但是也有其他實(shí)現(xiàn)方式硼莽,不過目前gcc 和微軟的編譯器都是將vptr放在對(duì)象內(nèi)存布局的最前面庶溶。
雖然我們知道vptr指向虛函數(shù)表,那么虛函數(shù)表具體存放在內(nèi)存哪個(gè)位置呢懂鸵,雖然這里我們已經(jīng)可以得到虛函數(shù)表的地址偏螺。實(shí)際上虛函數(shù)指針是在構(gòu)造函數(shù)執(zhí)行時(shí)初始化的,而虛函數(shù)表是存放在可執(zhí)行文件中的匆光。下面的一篇博客測(cè)試了微軟的編譯器將虛函數(shù)表存放在了目標(biāo)文件或者可執(zhí)行文件的常量段中套像,http://blog.csdn.net/vicness/article/details/3962767,不過我在gcc下的匯編文件中沒有找到vtbl的具體存放位置殴穴,主要是對(duì)可執(zhí)行文件的裝載和運(yùn)行原理還沒有深刻的理解凉夯,相信不久有了這些知識(shí)之后會(huì)很輕松的找到虛函數(shù)表到底存放在目標(biāo)文件的哪一個(gè)段中。
經(jīng)過測(cè)試采幌,在gcc編譯器的實(shí)現(xiàn)中虛函數(shù)表vtable存放在可執(zhí)行文件的只讀數(shù)據(jù)段.rodata中劲够。
C++虛函數(shù)的具體實(shí)現(xiàn)原理
基類定義了虛函數(shù),子類可以重寫該函數(shù)休傍,當(dāng)子類重新定義了父類的虛函數(shù)后征绎,父類指針根據(jù)賦給它的不同的子類指針,動(dòng)態(tài)地調(diào)用屬于子類的該函數(shù)磨取,且這樣的函數(shù)調(diào)用是無法在編譯期間確認(rèn)的人柿,而是在運(yùn)行期確認(rèn),也叫做遲綁定忙厌。在此模型中凫岖,non static 數(shù)據(jù)成員被放置到對(duì)象內(nèi)部,static數(shù)據(jù)成員逢净, static and nonstatic 函數(shù)成員均被放到對(duì)象之外哥放。對(duì)于虛函數(shù)的支持則分兩步完成:
1.每一個(gè)class產(chǎn)生一堆指向虛函數(shù)的指針歼指,放在表格之中。這個(gè)表格稱之為虛函數(shù)表(virtual table甥雕,vtbl)踩身。
2.每一個(gè)對(duì)象被添加了一個(gè)指針,指向相關(guān)的虛函數(shù)表vtbl社露。通常這個(gè)指針被稱為vptr挟阻。vptr的設(shè)定和重置都由每一個(gè)class的構(gòu)造函數(shù),析構(gòu)函數(shù)和拷貝賦值運(yùn)算符自動(dòng)完成峭弟。
介紹C++內(nèi)存管理(C ++的內(nèi)存模型是熱門問題)
在C++中附鸽,內(nèi)存分成5個(gè)區(qū),他們分別是堆孟害、棧拒炎、自由存儲(chǔ)區(qū)、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)挨务。
- 堆击你,就是那些由new分配的內(nèi)存塊,他們的釋放編譯器不去管谎柄,由我們的應(yīng)用程序去控制丁侄,一般一個(gè)new就要對(duì)應(yīng)一個(gè)delete。如果程序員沒有釋放掉朝巫,那么在程序結(jié)束后鸿摇,操作系統(tǒng)會(huì)自動(dòng)回收。分配方式類似鏈表劈猿。
- 自由存儲(chǔ)區(qū)拙吉,就是那些由malloc等分配的內(nèi)存塊,他和堆是十分相似的揪荣,不過它是用free來結(jié)束自己的生命的筷黔。
棧,由編譯器自動(dòng)分配和釋放仗颈,存放函數(shù)的參數(shù)值佛舱、局部變量的值等。* 棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中挨决,效率很高请祖,但是分配的內(nèi)存容量有限。 - 全局/靜態(tài)存儲(chǔ)區(qū)脖祈,全局變量和靜態(tài)變量被分配到同一塊內(nèi)存中肆捕,在以前的C語言中,全局變量又分為初始化的和未初始化的盖高,在C++里面沒有這個(gè)區(qū)分了福压,他們共同占用同一塊內(nèi)存區(qū)掏秩。
- 常量存儲(chǔ)區(qū),這是一塊比較特殊的存儲(chǔ)區(qū)荆姆,他們里面存放的是常量,不允許修改映凳。
C/C++的區(qū)別胆筒?
- 首先 C 包含 C 幾乎全部功能。
- C 比 C 多面向?qū)ο笳Z言部分诈豌。
- C 比 C 多泛型編程部分仆救。
- C 比 C 多 STL 部分。
面向?qū)ο蟮奶攸c(diǎn)矫渔,簡(jiǎn)單描述一下彤蔽?
一、三個(gè)基本特征
向?qū)ο蟮娜齻€(gè)基本特征是:封裝庙洼、繼承顿痪、多態(tài)。
封裝油够,也就是把客觀事物封裝成抽象的類蚁袭,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象操作,對(duì)不可信的進(jìn)行信息隱藏石咬。
繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能揩悄,并在無需重新編寫原來的類的情況下對(duì)這些功能進(jìn)行擴(kuò)展。要實(shí)現(xiàn)繼承鬼悠,可以通過“繼承”(Inheritance)和“組合”(Composition)來實(shí)現(xiàn)删性。
繼承概念的實(shí)現(xiàn)方式有三類:實(shí)現(xiàn)繼承、接口繼承和可視繼承焕窝。
? 實(shí)現(xiàn)繼承是指使用基類的屬性和方法而無需額外編碼的能力蹬挺;
? 接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實(shí)現(xiàn)的能力袜啃;
? 可視繼承是指子窗體(類)使用基窗體(類)的外觀和實(shí)現(xiàn)代碼的能力汗侵。
多態(tài)性(polymorphisn)是允許你將父對(duì)象設(shè)置成為和一個(gè)或更多的他的子對(duì)象相等的技術(shù),賦值之后群发,父對(duì)象就可以根據(jù)當(dāng)前賦值給它的子對(duì)象的特性以不同的方式運(yùn)作晰韵。簡(jiǎn)單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針熟妓。
實(shí)現(xiàn)多態(tài)雪猪,有二種方式,覆蓋起愈,重載只恨。
覆蓋译仗,是指子類重新定義父類的虛函數(shù)的做法。
重載官觅,是指允許存在多個(gè)同名函數(shù)纵菌,而這些函數(shù)的參數(shù)表不同(或許參數(shù)個(gè)數(shù)不同,或許參數(shù)類型不同休涤,或許兩者都不同)
inline函數(shù)的作用
C++內(nèi)聯(lián)函數(shù)提供了替代函數(shù)調(diào)用的方案咱圆,通過inline聲明,編譯器首先在函數(shù)調(diào)用處使用函數(shù)體本身語句替換了函數(shù)調(diào)用語句功氨,然后編譯替換后的代碼序苏。因此,通過內(nèi)聯(lián)函數(shù)捷凄,編譯器不需要跳轉(zhuǎn)到內(nèi)存其他地址去執(zhí)行函數(shù)調(diào)用忱详,也不需要保留函數(shù)調(diào)用時(shí)的現(xiàn)場(chǎng)數(shù)據(jù)。
虛函數(shù)的作用
虛函數(shù)的作用就是實(shí)現(xiàn)“動(dòng)態(tài)聯(lián)編”跺涤,也就是在程序的運(yùn)行階段動(dòng)態(tài)地選擇合適的成員函數(shù)匈睁。具體的實(shí)現(xiàn)方式是:在定義了虛函數(shù)后,可以在基類的派生類中對(duì)虛函數(shù)重新定義钦铁,在派生類中重新定義的函數(shù)應(yīng)與虛函數(shù)具有相同的形參個(gè)數(shù)和形參類型软舌。以實(shí)現(xiàn)統(tǒng)一的接口,不同定義過程牛曹。如果在派生類中沒有對(duì)虛函數(shù)重新定義佛点,則它繼承其基類的虛函數(shù)。編譯器在編譯過程中發(fā)現(xiàn)類的函數(shù)名前的關(guān)鍵字virtual后黎比,會(huì)自動(dòng)將其作為動(dòng)態(tài)聯(lián)編處理超营,即在程序運(yùn)行時(shí)動(dòng)態(tài)地選擇合適的成員函數(shù),
純虛函數(shù)的作用阅虫,純虛函數(shù)能否被實(shí)例化
純虛函數(shù)是在基類中聲明的虛函數(shù)演闭,它在基類中沒有定義,但要求任何派生類都要定義自己的實(shí)現(xiàn)方法颓帝。在基類中實(shí)現(xiàn)純虛函數(shù)的方法是在函數(shù)原型后加“=0”virtual void funtion1()=0
引入原因:
1米碰、為了方便使用多態(tài)特性,我們常常需要在基類中定義虛擬函數(shù)购城。
2吕座、在很多情況下,基類本身生成對(duì)象是不合情理的瘪板。例如吴趴,動(dòng)物作為一個(gè)基類可以派生出老虎、孔雀等子類侮攀,但動(dòng)物本身生成對(duì)象明顯不合常理锣枝。
含有純虛函數(shù)的類為抽象類厢拭,不能聲明對(duì)象,只是作為基類為派生類服務(wù)撇叁。除非在派生類中完全實(shí)現(xiàn)基類的所有虛函數(shù)供鸠,否則派生類也是抽象類,不能實(shí)例化對(duì)象陨闹。
抽象類不能定義對(duì)象回季,但是可以作為指針或或者引用類型使用。
類中哪些函數(shù)不能聲明為虛函數(shù)正林,原因
常見的不不能聲明為虛函數(shù)的有:普通函數(shù)(非成員函數(shù));靜態(tài)成員函數(shù)颤殴;內(nèi)聯(lián)成員函數(shù)觅廓;構(gòu)造函數(shù);友元函數(shù)涵但。
- 普通函數(shù)(非成員函數(shù))只能被overload杈绸,不能被override,聲明為虛函數(shù)也沒有什么意思矮瘟,因此編譯器會(huì)在編譯時(shí)邦定函數(shù)瞳脓。
- 構(gòu)造函數(shù)本來就是為了明確初始化對(duì)象成員才產(chǎn)生的,然而virtual function主要是為了再不完全了解細(xì)節(jié)的情況下也能正確處理對(duì)象澈侠。另外劫侧,virtual函數(shù)是在不同類型的對(duì)象產(chǎn)生不同的動(dòng)作,現(xiàn)在對(duì)象還沒有產(chǎn)生哨啃,如何使用virtual函數(shù)來完成你想完成的動(dòng)作烧栋。
- 內(nèi)聯(lián)函數(shù)就是為了在代碼中直接展開,減少函數(shù)調(diào)用花費(fèi)的代價(jià)拳球,虛函數(shù)是為了在繼承后對(duì)象能夠準(zhǔn)確的執(zhí)行自己的動(dòng)作审姓,這是不可能統(tǒng)一的。(再說了祝峻,inline函數(shù)在編譯時(shí)被展開魔吐,虛函數(shù)在運(yùn)行時(shí)才能動(dòng)態(tài)的邦定函數(shù))
- 靜態(tài)成員函數(shù)對(duì)于每個(gè)類來說只有一份代碼,所有的對(duì)象都共享這一份代碼莱找,他也沒有要?jiǎng)討B(tài)邦定的必要性酬姆。
- 因?yàn)镃++不支持友元函數(shù)的繼承,對(duì)于沒有繼承特性的函數(shù)沒有虛函數(shù)的說法宋距。
析構(gòu)函數(shù)能否為虛函數(shù)轴踱,為什么?
有多態(tài)的基類應(yīng)該聲明一個(gè)virtual析構(gòu)函數(shù)谚赎。如果class帶有任何virtual函數(shù)淫僻,他就應(yīng)該擁有一個(gè)virtual析構(gòu)函數(shù)诱篷。若基類的析構(gòu)函數(shù)不是虛函數(shù),當(dāng)基類指針pa指向用new運(yùn)算符生成的派生類對(duì)象B時(shí)雳灵,delete基類指針棕所,只會(huì)運(yùn)行基類的析構(gòu)函數(shù),而不會(huì)執(zhí)行派生類的析構(gòu)函數(shù)悯辙。
你對(duì)c++內(nèi)存這里有什么見解琳省,或者有什么好的設(shè)計(jì)理念
自己總結(jié)了幾點(diǎn),new躲撰,detele针贬,new[],delete[],構(gòu)造析購里面通常怎么設(shè)計(jì),虛析構(gòu)函數(shù)的概念 拢蛋,后來他又給我講解了一下c++喜歡用namespace這種機(jī)制桦他,類似于析購構(gòu)造的原理,一段結(jié)束后自動(dòng)釋放的原理谆棱。
我接著也說了一下自己對(duì)namespace經(jīng)常用到的地方(1)自動(dòng)鎖的原理經(jīng)常用到namespace快压,起到自動(dòng)調(diào)用析購的函數(shù)(2)還有喜歡把一個(gè)class也封裝在一個(gè)namespace里面,
實(shí)現(xiàn)編譯器處理虛函數(shù)表應(yīng)該如何處理
C++內(nèi)存分配
堆垃瞧、棧蔫劣、自由存儲(chǔ)區(qū)、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)
程序編譯鏈接的過程和函數(shù)找不到在哪個(gè)階段報(bào)錯(cuò)
動(dòng)態(tài)綁定的介紹
動(dòng)態(tài)綁定:運(yùn)行時(shí)綁定个从,通過地址實(shí)現(xiàn)
只有采用“指針->函數(shù)()”或“引用變量.函數(shù)()”的方式調(diào)用C++類中的虛函數(shù)才會(huì)執(zhí)行動(dòng)態(tài)綁定脉幢。對(duì)于C++中的非虛函數(shù),因?yàn)槠洳痪邆鋭?dòng)態(tài)綁定的特征信姓,所以不管采用什么樣的方式調(diào)用鸵隧,都不會(huì)執(zhí)行動(dòng)態(tài)綁定。
即所謂動(dòng)態(tài)綁定意推,就是基類的指針或引用有可能指向不同的派生類對(duì)象豆瘫,對(duì)于非虛函數(shù),執(zhí)行時(shí)實(shí)際調(diào)用該函數(shù)的對(duì)象類型即為該指針或引用的靜態(tài)類型(基類類型)菊值;而對(duì)于虛函數(shù)外驱,執(zhí)行時(shí)實(shí)際調(diào)用該函數(shù)的對(duì)象類型為該指針或引用所指對(duì)象的實(shí)際類型。
引用是否能實(shí)現(xiàn)動(dòng)態(tài)綁定腻窒,為什么引用可以實(shí)現(xiàn)
可以昵宇,引用和指針可以實(shí)現(xiàn)動(dòng)態(tài)綁定
介紹所有的構(gòu)造函數(shù)
默認(rèn)構(gòu)造函數(shù)
構(gòu)造函數(shù)
復(fù)制構(gòu)造函數(shù)
什么情況下要給類寫拷貝構(gòu)造函數(shù)
深拷貝時(shí)。類具有指針成員時(shí)儿子。
成員初始化列表的概念
構(gòu)造函數(shù)初始化列表以一個(gè)冒號(hào)開始瓦哎,接著是以逗號(hào)分隔的數(shù)據(jù)成員列表,每個(gè)數(shù)據(jù)成員后面跟一個(gè)放在括號(hào)中的初始化式。
1.成員類型是沒有默認(rèn)構(gòu)造函數(shù)的類蒋譬。若沒有提供顯示初始化式割岛,則編譯器隱式使用成員類型的默認(rèn)構(gòu)造函數(shù),若類沒有默認(rèn)構(gòu)造函數(shù)犯助,則編譯器嘗試使用默認(rèn)構(gòu)造函數(shù)將會(huì)失敗癣漆。
2.const成員或引用類型的成員。因?yàn)閏onst對(duì)象或引用類型只能初始化剂买,不能對(duì)他們賦值惠爽。
為什么用成員初始化列表會(huì)快一些
初始化列表是直接初始化,利用的函數(shù)匹配原理瞬哼,調(diào)用的是構(gòu)造函數(shù)或者copy構(gòu)造函數(shù)(根據(jù)初始化的參數(shù)來決定婚肆,內(nèi)置類型為構(gòu)造函數(shù),類類型為copy構(gòu)造函數(shù))坐慰。在函數(shù)體里復(fù)制旬痹,會(huì)多調(diào)用一次默認(rèn)構(gòu)造函數(shù)。
C語言變量存放位置
C++垃圾回收讨越,shared_ptr的引用計(jì)數(shù)出現(xiàn)循環(huán)引用怎么辦
C中的malloc和free做了哪些事情,free怎么知道free多長(zhǎng)永毅,C++中的delete又怎么知道delete多長(zhǎng)
在heap中進(jìn)行內(nèi)存分配把跨,以鏈表形式進(jìn)行記錄。free時(shí)先判斷是不是malloc分配的沼死,然后釋放着逐。將free標(biāo)志設(shè)置為1
指針和引用的區(qū)別?
- 引用必須被初始化意蛀,指針不必耸别。
- 引用初始化以后不能被改變沸手,指針可以改變所指的對(duì)象虐秦。
- 不存在指向空值的引用沼填,但是存在指向空值的指針搏色。
6野指針的問題山上。
1嗦玖、指針變量沒有被初始化澜掩。 任何指針變量在剛被創(chuàng)建的時(shí)候不會(huì)自動(dòng)成為NULL指針贯涎,它的缺省值是隨機(jī)的谴麦。所以指針變量在創(chuàng)建的時(shí)候蠢沿,要么設(shè)置為NULL,要么指向合法的內(nèi)存匾效。
2舷蟀、指針p被free/delete之后,沒有置為NULL(最好加一句p = NULL;)。他們只是把指針指向的內(nèi)存給釋放掉野宜,并沒有把指針本身干掉扫步。
3、指針操作超越了變量的作用范圍速缨。不要返回指向棧內(nèi)存的指針或引用锌妻,因?yàn)闂?nèi)存在函數(shù)結(jié)束時(shí)會(huì)被釋放。
指針(各種指針旬牲,指針數(shù)組仿粹,數(shù)組指針,函數(shù)指針原茅,n級(jí)指針)
char * a=new char a[]; sizeof(a)大小
4字節(jié)吭历,指針的大小。
靜態(tài)動(dòng)態(tài)數(shù)組區(qū)別
動(dòng)態(tài)數(shù)組可以再編譯時(shí)確定數(shù)組大小擂橘。存儲(chǔ)的位置不一樣晌区。
new delete new[] delete [] malloc free底層實(shí)現(xiàn)
http://blog.codinglabs.org/articles/a-malloc-tutorial.html
overlode override
77.unsigned long* p1=(unsigned long* )0x810000(地址)
unsigned char* p2=(unsigned char* )0x810000(地址)
p1+5=? p2+5=?
能否用memset實(shí)例化一個(gè)類?
不能通贞,禁止用memcpy朗若、memset初始化非POD對(duì)象。由于非POD類型比如非集合類型的class對(duì)象昌罩,可能存在虛函數(shù)哭懈,內(nèi)存布局不確定,跟編譯器有關(guān)茎用,濫用內(nèi)存拷貝可能會(huì)導(dǎo)致嚴(yán)重的問題遣总。
無法復(fù)制虛函數(shù)表。
new/delete和malloc/free的區(qū)別
malloc與free是C++/C語言的標(biāo)準(zhǔn)庫函數(shù)轨功,new/delete是C++的運(yùn)算符旭斥。它們都可用于申請(qǐng)動(dòng)態(tài)內(nèi)存和釋放內(nèi)存。
對(duì)于非內(nèi)部數(shù)據(jù)類型的對(duì)象而言古涧,光用maloc/free無法滿足動(dòng)態(tài)對(duì)象的要求垂券。對(duì)象在創(chuàng)建的同時(shí)要自動(dòng)執(zhí)行構(gòu)造函數(shù),對(duì)象在消亡之前要自動(dòng)執(zhí)行析構(gòu)函數(shù)羡滑。由于malloc/free是庫函數(shù)而不是運(yùn)算符圆米,不在編譯器控制權(quán)限之內(nèi),不能夠把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free啄栓。
因此C++語言需要一個(gè)能完成動(dòng)態(tài)內(nèi)存分配和初始化工作的運(yùn)算符new娄帖,以及一個(gè)能完成清理與釋放內(nèi)存工作的運(yùn)算符delete。注意new/delete不是庫函數(shù)昙楚。
我們不要企圖用malloc/free來完成動(dòng)態(tài)對(duì)象的內(nèi)存管理近速,應(yīng)該用new/delete。由于內(nèi)部數(shù)據(jù)類型的“對(duì)象”沒有構(gòu)造與析構(gòu)的過程,對(duì)它們而言malloc/free和new/delete是等價(jià)的削葱。
* malloc/free的使用要點(diǎn)
void * malloc(size_t size);
int *p = (int *) malloc(sizeof(int) * length);
我們應(yīng)當(dāng)把注意力集中在兩個(gè)要素上:“類型轉(zhuǎn)換”和“sizeof”奖亚。
- malloc返回值的類型是void * ,所以在調(diào)用malloc時(shí)要顯式地進(jìn)行類型轉(zhuǎn)換析砸,將void * 轉(zhuǎn)換成所需要的指針類型昔字。
- malloc函數(shù)本身并不識(shí)別要申請(qǐng)的內(nèi)存是什么類型,它只關(guān)心內(nèi)存的總字節(jié)數(shù)首繁。我們通常記不住int, float等數(shù)據(jù)類型的變量的確切字節(jié)數(shù)作郭。例如int變量在16位系統(tǒng)下是2個(gè)字節(jié),在32位下是4個(gè)字節(jié)弦疮;而float變量在16位系統(tǒng)下是4個(gè)字節(jié)夹攒,在32位下也是4個(gè)字節(jié)。
* new/delete的使用要點(diǎn)
int *p1 = (int *)malloc(sizeof(int) * length);
int *p2 = new int[length];
這是因?yàn)閚ew內(nèi)置了sizeof胁塞、類型轉(zhuǎn)換和類型安全檢查功能咏尝。對(duì)于非內(nèi)部數(shù)據(jù)類型的對(duì)象而言,new在創(chuàng)建動(dòng)態(tài)對(duì)象的同時(shí)完成了初始化工作啸罢。
鏈表和數(shù)組的區(qū)別
const 和 static 用法编检。
這個(gè)比較多, 詳細(xì)的可以自己在網(wǎng)上找找。
? const 關(guān)鍵字: 用在局部變量上, 用在類成員變量上, 用在類成員函數(shù)后面...
? static 關(guān)鍵字: 用在全局變量上, 用在局部變量上,用在類成員變量上, 用在類成員函數(shù)上...
計(jì)算下面幾個(gè)類的大小
? class A {};: sizeof(A) = 1;
? class A { virtual Fun(){} };: sizeof(A) = 4(32位機(jī)器)/8(64位機(jī)器);
? class A { static int a; };: sizeof(A) = 1;
? class A { int a; };: sizeof(A) = 4;
? class A { static int a; int b; };: sizeof(A) = 4;
已知某類:
class A
{
public:
A(int x){}
}
問:A a = 1;是否正確, 如果正確, 那么它調(diào)用了哪些函數(shù)扰才?
? 由于 A 類的構(gòu)造函數(shù)沒有聲明為explicit因此可以 int 類型強(qiáng)制轉(zhuǎn)換來蒙谓。因此, 該表達(dá)式正確。
? 對(duì)于沒有優(yōu)化過的編譯器: 先將 1 轉(zhuǎn)化為 A 類型(構(gòu)造函數(shù)), 再將其賦值給 a 變量(拷貝賦值函數(shù))训桶。
? 對(duì)于優(yōu)化了的編譯器: 直接用 1 來構(gòu)造變量 a(構(gòu)造函數(shù))。
代碼找錯(cuò):
char* str = "hello"; 1)
char* p = new char[5]; 2)
strcpy(p, str); 3)
cout << p << endl; 4)
? 編譯通過, 運(yùn)行時(shí)出錯(cuò)酣倾。
? 2) 中的數(shù)組申請(qǐng)?zhí)? 無法容納下 "hello" 的大小舵揭。 因?yàn)樽址竺孢€有結(jié)束符('\0')。
? 與 new 搭配的是 delete躁锡。2) 中 new 了資源沒有 delete 掉午绳。
class {}內(nèi)部實(shí)現(xiàn)的函數(shù)。
默認(rèn)構(gòu)造函數(shù), 默認(rèn)析構(gòu)函數(shù), 拷貝賦值函數(shù), (移動(dòng)構(gòu)造函數(shù), 移動(dòng)賦值函數(shù)) 析構(gòu)函數(shù)映之,賦值運(yùn)算符
C 語言的特性
C 是面向?qū)ο蟮恼Z言, 自然有面向?qū)ο蟮恼Z言的特性: 封裝, 繼承, 多態(tài)拦焚。
C 也是泛型編程語言, 自然也有泛型編程語言的特性。
重載和重寫的區(qū)別
重載要求相同的函數(shù)名, 不同的參數(shù)列表杠输。僅返回值不同的函數(shù)不能重載赎败。
重寫要求父類是虛函數(shù), 子類改寫其函數(shù)體。要求函數(shù)簽名一模一樣蠢甲。
對(duì)象復(fù)用的了解
零拷貝的了解
手寫實(shí)現(xiàn)智能指針類
1僵刮,方法重載,何時(shí)用重載,為什么要使用重載搞糕?而不是把一個(gè)方法名字換成不同的勇吊。
菱形繼承與接口目的
? 面向?qū)ο蟮娜筇匦?br>
? MVC設(shè)計(jì)模式