C++面试宝典 基本语言(三)
生活随笔
收集整理的這篇文章主要介紹了
C++面试宝典 基本语言(三)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
如果同時定義了兩個函數(shù),一個帶const,一個不帶,會有問題嗎?
- 不會,這相當于函數(shù)的重載
請你來說一說隱式類型轉(zhuǎn)換
- 首先,對于內(nèi)置類型,低精度的變量給高精度變量賦值會發(fā)生隱式類型轉(zhuǎn)換,? ?int? ->? double
- 其次,對于只存在單個參數(shù)的構(gòu)造函數(shù)的對象構(gòu)造來說,函數(shù)調(diào)用可以直接使用該參數(shù)傳入,編譯器會自動調(diào)用其構(gòu)造函數(shù)生成臨時對象
注意事項
- “可以用單個形參進行調(diào)用” 并不是指構(gòu)造函數(shù)只能有一個形參,而是它可以有多個形參,但那些形參都是有默認實參的。 那么,什么是“隱式轉(zhuǎn)換”呢? 上面這句話也說了,是從 構(gòu)造函數(shù)形參類型 到 該類類型 的一個編譯器的自動轉(zhuǎn)換。
- 代碼中可以看到,isSameISBN函數(shù)是期待一個BOOK類類型形參的,但我們卻傳遞了一個string類型的給它,這不是它想要的啊!還好,BOOK類中有個構(gòu)造函數(shù),它使用一個string類型實參進行調(diào)用,編譯器調(diào)用了這個構(gòu)造函數(shù),隱式地將stirng類型轉(zhuǎn)換為BOOK類型(構(gòu)造了一個BOOK臨時對象),再傳遞給isSameISBN函數(shù)。 隱式類類型轉(zhuǎn)換還是會帶來風(fēng)險的,正如上面標記,隱式轉(zhuǎn)換得到類的臨時變量,完成操作后就消失了,我們構(gòu)造了一個完成測試后被丟棄的對象。 我們可以通過explicit聲明來抑制這種轉(zhuǎn)換:
- explicit BOOK(string ISBN,float price=0.0f):_bookISBN(ISBN),_price(price){}
- explicit關(guān)鍵字只能用于類內(nèi)部的構(gòu)造函數(shù)聲明上.這樣一來,BOOK類構(gòu)造函數(shù)就不能用于隱式地創(chuàng)造對象了
- 可以使用一個實參進行調(diào)用,不是指構(gòu)造函數(shù)只能有一個形參。 隱式類類型轉(zhuǎn)換容易引起錯誤,除非你有明確理由使用隱式類類型轉(zhuǎn)換,否則,將可以用一個實參進行調(diào)用的構(gòu)造函數(shù)都聲明為explicit。 ? ?
- ?explicit只能用于類內(nèi)部構(gòu)造函數(shù)的聲明。它雖然能避免隱式類型轉(zhuǎn)換帶來的問題,但需要用戶能夠顯式創(chuàng)建臨時對象(對用戶提出了要求)。
說說你了解的類型轉(zhuǎn)換
- reinterpret_cast:可以用于任意類型的指針之間的轉(zhuǎn)換,對轉(zhuǎn)換的結(jié)果不做任何保證
- dynamic_cast:這種其實也是不被推薦使用的,更多使用static_cast,dynamic本身只能用于存在虛函數(shù)的父子關(guān)系的強制類型轉(zhuǎn)換,對于指針,轉(zhuǎn)換失敗則返回nullptr,對于引用,轉(zhuǎn)換失敗會拋出異常。(1)dynamic_cast是運行時處理的,運行時要進行類型檢查,而其他三種都是編譯時完成的;(2)不能用于內(nèi)置基本數(shù)據(jù)類型間的強制轉(zhuǎn)換;(3)使用dynamic_cast進行轉(zhuǎn)換時,基類中一定要有虛函數(shù),否則編譯不通過;(4)dynamic_cast轉(zhuǎn)換若成功,返回的是指向類的指針或引用;若失敗則會返回NULL;(5)在類的轉(zhuǎn)換時,在類層次間進行上行轉(zhuǎn)換時,dynamic_cast和static_cast的效果是一樣的。在進行下行轉(zhuǎn)換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。向下轉(zhuǎn)換的成敗取決于將要轉(zhuǎn)換的類型,即要強制轉(zhuǎn)換的指針所指向的對象實際類型與將要轉(zhuǎn)換后的類型一定要相同,否則轉(zhuǎn)換失敗。? 下行轉(zhuǎn)換,使用基類class? 創(chuàng)建 其派生類對象的時候,新建的對象只可以使用 基類的相關(guān)public、protected內(nèi)容 和 本派生類所創(chuàng)建的獨有的方法
- 參考此例子??
參考鏈接
- C++中四種cast(強制)轉(zhuǎn)換?
- const_cast:對于未定義const版本的成員函數(shù),我們通常需要使用const_cast來去除const引用對象的const,完成函數(shù)調(diào)用。另外一種使用方式,結(jié)合static_cast,可以在非const版本的成員函數(shù)內(nèi)添加const,調(diào)用完const版本的成員函數(shù)后,再使用const_cast去除const限定。
- static_cast:完成基礎(chǔ)數(shù)據(jù)類型;同一個繼承體系中類型的轉(zhuǎn)換;任意類型與空指針類型void* 之間的轉(zhuǎn)換。
參考鏈接
- 你必須知道的指針基礎(chǔ)-8.棧空間與堆空間?
- 棧空間和堆空間大小
?請你來說一說C++函數(shù)棧空間的最大值
- 默認是1M,不過可以調(diào)整?
- 補充:window和Linux不一樣,linux如圖stack size所示 為8kb,win為2kb;而堆本質(zhì)是使用鏈表的形式申請內(nèi)存空間,和操作系統(tǒng)的虛擬內(nèi)存掛鉤,一般大小為2G
請你來說一說extern“C”
- C++調(diào)用C函數(shù)需要extern C,因為C語言沒有函數(shù)重載
參考鏈接
- extern “C”的作用詳解
- extern "C":實現(xiàn)C++和C的混合編程
請你回答一下new/delete與malloc/free的區(qū)別是什么
- 首先,new/delete是C++的關(guān)鍵字,而malloc/free是C語言的庫函數(shù),后者使用必須指明申請內(nèi)存空間的大小,對于類類型的對象,后者不會調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
補充
- 1、new分配內(nèi)存按照數(shù)據(jù)類型進行分配,malloc分配內(nèi)存按照指定的大小分配;
- 2、new返回的是指定對象的指針,而malloc返回的是void*,因此malloc的返回值一般都需要進行類型轉(zhuǎn)化。
- 3、new不僅分配一段內(nèi)存,而且會調(diào)用構(gòu)造函數(shù),malloc不會。
- 4、new分配的內(nèi)存要用delete銷毀,malloc要用free來銷毀;delete銷毀的時候會調(diào)用對象的析構(gòu)函數(shù),而free則不會。
- 5、new是一個操作符可以重載,malloc是一個庫函數(shù)。
- 6、malloc分配的內(nèi)存不夠的時候,可以用realloc擴容。new沒用這樣操作。
- 7、new如果分配失敗了會拋出bad_malloc的異常,而malloc失敗了會返回NULL。
- 8、申請數(shù)組時:new[]一次分配所有內(nèi)存,多次調(diào)用構(gòu)造函數(shù),搭配使用delete[]。delete[]多次調(diào)用析構(gòu)函數(shù),銷毀數(shù)組中的每個對象。而malloc則只能sizeof(int) * n。
參考鏈接
- 請你來回答一下new和malloc的區(qū)別
請你說說你了解的RTTI
- 運行時類型檢查,在C++層面主要體現(xiàn)在dynamic_cast和typeid,VS中虛函數(shù)表的-1位置存放了指向type_info的指針。對于存在虛函數(shù)的類型,typeid和dynamic_cast都會去查詢type_info
參考鏈接
- RTTI
- C++中的RTTI機制
- Chapter12:多態(tài)——從虛函數(shù)表到RTTI(二)
請你說說虛函數(shù)表具體是怎樣實現(xiàn)運行時多態(tài)的?
- 子類若重寫父類虛函數(shù),虛函數(shù)表中,該函數(shù)的地址會被替換,對于存在虛函數(shù)的類的對象,在VS中,對象的對象模型的頭部存放指向虛函數(shù)表的指針,通過該機制實現(xiàn)多態(tài)。
請你說說C語言是怎么進行函數(shù)調(diào)用的?
- 每一個函數(shù)調(diào)用都會分配函數(shù)棧,在棧內(nèi)進行函數(shù)執(zhí)行過程。調(diào)用前,先把返回地址壓棧,然后把當前函數(shù)的esp指針壓棧。
請你說說C語言參數(shù)壓棧順序?
- 從右到左
請你說說C++如何處理返回值?
生成一個臨時變量,把它的引用作為函數(shù)參數(shù)傳入函數(shù)內(nèi)。
請你回答一下C++中拷貝賦值函數(shù)的形參能否進行值傳遞?
- 不能。如果是這種情況下,調(diào)用拷貝構(gòu)造函數(shù)的時候,首先要將實參傳遞給形參,這個傳遞的時候又要調(diào)用拷貝構(gòu)造函數(shù)。如此循環(huán),無法完成拷貝,棧也會滿。
請你回答一下malloc與new區(qū)別
- malloc需要給定申請內(nèi)存的大小,返回的void* 指針需要強轉(zhuǎn)
- new會調(diào)用構(gòu)造函數(shù),不用指定內(nèi)存大小,返回的指針不用強轉(zhuǎn)
請你說一說select
- select在使用前,先將需要監(jiān)控的描述符對應(yīng)的bit位置1,然后將其傳給select,當有任何一個事件發(fā)生時,select將會返回所有的描述符,需要在應(yīng)用程序自己遍歷去檢查哪個描述符上有事件發(fā)生,效率很低,并且其不斷在內(nèi)核態(tài)和用戶態(tài)進行描述符的拷貝,開銷很大
?請你說說fork,wait,exec函數(shù)
- 父進程產(chǎn)生子進程使用fork拷貝出來一個父進程的副本,此時只拷貝了父進程的頁表,兩個進程都讀同一塊內(nèi)存,當有進程寫的時候使用寫實拷貝機制分配內(nèi)存
- exec函數(shù)可以加載一個elf文件去替換父進程,從此父進程和子進程就可以運行不同的程序了。fork從父進程返回子進程的pid,從子進程返回0.調(diào)用了wait的父進程將會發(fā)生阻塞,直到有子進程狀態(tài)改變,執(zhí)行成功返回0,錯誤返回-1。
- exec執(zhí)行成功則子進程從新的程序開始運行,無返回值,執(zhí)行失敗返回-1
請你回答一下靜態(tài)函數(shù)和虛函數(shù)的區(qū)別
- 靜態(tài)函數(shù)在編譯的時候就已經(jīng)確定運行時機,虛函數(shù)在運行的時候動態(tài)綁定。虛函數(shù)因為用了虛函數(shù)表機制,調(diào)用的時候會增加一次內(nèi)存開銷,動態(tài)切換
請你說一說重載和覆蓋
- 重載:兩個函數(shù)名相同,但是參數(shù)列表不同(個數(shù),類型),返回值類型沒有要求,在同一作用域中
- 重寫:子類繼承了父類,父類中的函數(shù)是虛函數(shù),在子類中重新定義了這個虛函數(shù),這種情況是重寫
請你說一說static關(guān)鍵字
- 1.加了static關(guān)鍵字的全局變量只能在本文件中使用。例如在a.c中定義了static int a=10;那么在b.c中用extern int a是拿不到a的值,a的作用域只在a.c中。
- 2.static定義的靜態(tài)局部變量分配在數(shù)據(jù)段上,普通的局部變量分配在棧上,會因為函數(shù)棧幀的釋放而被釋放掉。
- 3. 對一個類中成員變量和成員函數(shù)來說,加了static關(guān)鍵字,則此變量/函數(shù)就沒有了this指針了,必須通過類名才能訪問
請你說一說strcpy和strlen
- strcpy是字符串拷貝函數(shù),原型:? char *strcpy(char* dest, const char *src);
- 從src逐字節(jié)拷貝到dest,直到遇到'\0'結(jié)束,因為沒有指定長度,可能會導(dǎo)致拷貝越界,造成緩沖區(qū)溢出漏洞,安全版本是strncpy函數(shù)。
- strlen函數(shù)是計算字符串長度的函數(shù),返回從開始到'\0'之間的字符個數(shù)。
總結(jié)
以上是生活随笔為你收集整理的C++面试宝典 基本语言(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。