1.數(shù)組名和指針的區(qū)別狸相?
明確一點數(shù)組名不是指針,可以通過sizeof來驗證打瘪。其本質是指代數(shù)組這樣一個數(shù)據(jù)結構。
數(shù)組名在表現(xiàn)很像const指針指針傻昙,不可以被改變(被賦值闺骚,++,--)妆档,可以用*來取對象僻爽,作為指針參數(shù),可以+整數(shù)
做為形參的數(shù)組名失去了其數(shù)據(jù)結構的本質內涵贾惦,其本質是一個指針进泼。
2.引用類型和指針的區(qū)別
從反匯編的角度看,引用的本質是一個由編譯器管理的指針纤虽。其表現(xiàn)出來的語法特征和其所引用的對象一致。
作為函數(shù)參數(shù)時绞惦,和指針一樣逼纸,真正傳遞的是指針,而非對象的拷貝济蝉,較少了堆椊芄簦空間的使用,而且可以在函數(shù)體內可以對所指的對象進行修改王滤。
引用不可以被修改贺嫂,以失去了指針的靈活性為代價,提高了程序安全性雁乡。
3.const總結
const的作用是希望通過對指定const屬性第喳,保證變量不被錯誤修改,提高代碼的安全性踱稍。
修飾變量:變成了常量曲饱,不可以被修改悠抹,其他操作不受影響。編譯器在編譯時將用到該變量的地方替換成對應的值扩淀。與#define的替換相比楔敌,const保留了變量的類型屬性,可以做類型檢驗驻谆。
修飾指針:作用在指針本身卵凑,則該指針不能被修改(const指針),所以必須初始化胜臊;作用在其指向的對象上勺卢,則不能通過該指針修改其指向的對象;綁定常量的引用必須是指向常量的引用区端,指向常量的引用綁定的未必是常量值漫。
修飾引用:不能夠通過該引用修改其綁定的對象。綁定常量的引用必須是指向常量的引用织盼,指向常量的引用綁定的未必是常量杨何。
修飾函數(shù):修飾隱式的this指針,將this指針設置為指向常量的指針沥邻,所以不能在函數(shù)體內修改數(shù)據(jù)成員危虱。
4.new/delete和malloc/free的區(qū)別
new/delete最終調用malloc/free來申請和釋放內存。
c++封裝了new和delete完成為對象分配內存唐全,調用構造函數(shù)埃跷,調用析構函數(shù),釋放內存工作邮利。
使用上比malloc和free更加方便弥雹,不用指定大小延届;引入異常bad_alloc剪勿。
new和delete通過調用operator?new和operator?delete來分配和釋放內存,?而這兩個函數(shù)可以重載方庭,為程序員自己實現(xiàn)內存管理提供了方便厕吉。
5?struct和class的區(qū)別
在功能上基本沒有什么區(qū)別,class能做到事情struct基本能做械念。struct可以有成員函數(shù)头朱,可以繼承,可以有虛函數(shù)(實現(xiàn)多態(tài))龄减。
區(qū)別在于默認的訪問控制:
6.const和define的區(qū)別
處理階段:const在編譯運行階段使用项钮,define在編譯預處理階段展開
存儲方式:const需要分配內存來存儲常量,而define不用分配內存
安全性:編譯器會對const做類型檢查更加安全。
作用域:默認情況下const的作用范圍是文件內部寄纵,多個文件共享需要使用extend?鳖敷,#define的作用范圍是全局,多個文件定義define同名會報錯程拭。
7.const和static的區(qū)別
內存區(qū)域:
8.const和static在類中使用的注意事項
static成員不屬于任何對象定踱,而是被他們共享。
靜態(tài)數(shù)據(jù)成員應該在類的外部定義恃鞋。
因為沒有this指針崖媚,static成員函數(shù)不能用const修飾,也不能訪問非靜態(tài)成員恤浪。
9.c++內存管理
10.內聯(lián)函數(shù)
將函數(shù)指定為內聯(lián)函數(shù)(inline)畅哑,調用位置上內聯(lián)展開,避免函數(shù)調用的開銷(堆棧維護水由,調整指令)荠呐。應用在規(guī)模小,流程直接砂客,頻繁調用的函數(shù)泥张。
將代碼放在符號表里,在調用點上展開鞠值。
內聯(lián)說明只是向編譯器發(fā)出一個請求媚创,編譯器可以忽略這個請求。編譯器優(yōu)化時彤恶,也可能將沒有inline說明的函數(shù)展開成內聯(lián)函數(shù)钞钙。
11.多態(tài)和虛函數(shù)
C++通過虛函數(shù)實現(xiàn)動態(tài)綁定,也就是多態(tài)声离。
動態(tài)綁定是根據(jù)對象本身芒炼,而不是指針或引用的類型來確定具體調用的函數(shù)。具體實現(xiàn)是在對象中維護一個虛函數(shù)表指針术徊,同個虛函數(shù)表中存儲了對象調用的函數(shù)的指針本刽。
虛函數(shù)通過虛函數(shù)指針和虛函數(shù)表來實現(xiàn)動態(tài)綁定。
編譯器編譯時弧关,為每個有虛函數(shù)的類生成一個虛函數(shù)表(一個一維數(shù)組),用來存儲該類的虛函數(shù)地址唤锉。
編譯器為每個對象提供一個指向虛表的指針世囊。(在32位機器的內存上看,是其前4個字節(jié)窿祥,這也是為什么有虛函數(shù)的類型的sizeof多4個字節(jié)的原因)株憾。
指向虛表的指針的初始化在構造函數(shù)中進行。
虛函數(shù)的位置,按照先后順序排列嗤瞎。
子類復制一份父類的虛函數(shù)表墙歪,替換重寫的虛函數(shù)地址,新加的虛函數(shù)依此放在表尾贝奇。
12.C++中的重載和重寫的區(qū)別:
重載:名稱相同參數(shù)不同虹菲。對操作相識的函數(shù),用相同的名字掉瞳,方便程序員的理解毕源,減輕起名字,記名字的負擔陕习。
重寫:同名同參數(shù)霎褐,虛函數(shù),子類將父類覆蓋掉(在虛函數(shù)表中覆蓋掉)该镣,即使通過強制類型轉化也不能訪問(對指針和引用而言)冻璃。
重定義:同名(參數(shù)可同可不同),基類中的函數(shù)被隱藏损合,子類對象無法直接訪問省艳。
13.面向對象的三個特征
繼承申屹,多態(tài)植阴,封裝磅废。
繼承:本質是代碼復制减宣。
多態(tài):多態(tài)和虛函數(shù)
封裝:將數(shù)據(jù)和和對操作封裝到放在一起矫渔。
14.析構函數(shù)一般寫成虛函數(shù)的原因?
delete父類指針時雹有,可以調用對像真正的析構函數(shù)剥汤。否則可能會出錯免姿,如子類中有指針類型擦耀,并且申請了內存棉圈,這時就會造成內存泄漏。
15.構造函數(shù)為什么一般不定義為虛函數(shù)
析構函數(shù)通過虛表來調用的眷蜓,而指向虛表的指針是在構造函數(shù)中初始化的分瘾,這是個矛盾。
16.構造函數(shù)或者析構函數(shù)中調用虛函數(shù)會怎樣
結果上來看和調用普通函數(shù)無異吁系。即基類調用基類的虛函數(shù)德召,派生類調用派生類的虛函數(shù)。
17.純虛函數(shù)
18.引用是否能實現(xiàn)動態(tài)綁定汽纤,為什么引用可以實現(xiàn)
引用和指針的靜態(tài)類型和動態(tài)類型可以不一樣上岗。
靜態(tài)類型:變量聲明時的類型或表達式生成的類型。編譯時已經(jīng)知道蕴坪。
動態(tài)類型:變量或表達式表示的內存的對象的類型肴掷。
19.深拷貝和淺拷貝的區(qū)別(舉例說明深拷貝的安全性)
在有指針成員的情況下敬锐,淺拷貝只是將指針指向已存在的內存。即兩個對象的指針成員指向的是同一內存區(qū)域呆瞻。
深拷貝的做法是申請一個內存復制一份台夺,并將新對象指針指向備份區(qū)。
安全性:淺拷貝如果修改了指針指向的內容痴脾,將對兩個對象都有影響颤介。
20.對象復用的了解,零拷貝的了解
對象池:對象池通過對象復用的方式來避免重復創(chuàng)建對象明郭,它會事先創(chuàng)建一定數(shù)量的對象放到池中买窟,當用戶需要創(chuàng)建對象的時候,直接從對象池中獲取即可薯定,用完對象之后再放回到對象池中始绍,以便復用。
適用性:類的實例可重用话侄。類的實例化過程開銷較大亏推。類的實例化的頻率較高。
零拷貝:emplace_back
21.什么情況下會調用拷貝構造函數(shù)
(1)用類的一個對象去初始化另一個對象時
(2)當函數(shù)的形參是類的對象時(也就是值傳遞時)年堆,如果是引用傳遞則不會調用
(3)當函數(shù)的返回值是類的對象或引用時
22.結構體內存對齊方式和為什么要進行內存對齊吞杭?
23.內存泄露的定義,如何檢測與避免变丧?
申請的堆沒有被釋放芽狗,該內存不能在被利用。
24.手寫實現(xiàn)智能指針類
25.調試程序的方法
26.C++的四種強制轉換(C++不是類型安全的)
static_cast?,?dynamic_cast?,?const_cast?,?reinterpret_cast
static_cast:可以實現(xiàn)C++中內置基本數(shù)據(jù)類型之間的相互轉換痒蓬。
const_cast:?操作不能在不同的種類間轉換童擎。相反,它僅僅把一個它作用的表達式轉換成常量攻晒。它可以使一個本來不是const類型的數(shù)據(jù)轉換成const類型的顾复,或者把const屬性去掉。
reinterpret_cast:有著和C風格的強制轉換同樣的能力鲁捏。它可以轉化任何內置的數(shù)據(jù)類型為其他任何的數(shù)據(jù)類型芯砸,也可以轉化任何指針類型為其他的類型。它甚至可以轉化內置的數(shù)據(jù)類型為指針给梅,無須考慮類型安全或者常量的情形假丧。不到萬不得已絕對不用。
dynamic_cast:1)運行時處理动羽,類型檢查包帚;2)不能用于內置的基本數(shù)據(jù)類型的強制轉換;3)轉換如果成功的話返回的是指向類的指針或引用曹质,轉換失敗的話則會返回NULL(指針類型婴噩,如果是應用類型,拋出bad_cast異常)羽德;4)使用dynamic_cast進行轉換的几莽,基類中一定要有虛函數(shù),否則編譯不通過宅静;5)
27.遇到coredump要怎么調試
28.調試程序的方法
29.模板的用法與適用場景
模板是C++泛型編程的基礎章蚣。
使用:template??//關鍵字+<模板參數(shù)列表>
非類型模板參數(shù):
應用場景:除了參數(shù)類型不一樣外,其他的內容全部一樣(函數(shù)體)姨夹,用模板纤垂,而不是每一個類型都寫一個函數(shù)。
特化:模板的一個獨立的定義磷账,其中一個或多個參數(shù)被指定為特定的類型峭沦。通用模板不能適應所有情況。(特殊情況特殊處理)
30.成員初始化列表的概念逃糟,為什么用成員初始化列表會快一些
概念:以一個冒號開始吼鱼,接著是以逗號分隔的數(shù)據(jù)成員列表,每個數(shù)據(jù)成員后面跟一個放在括號中的初始化式绰咽,對成員進行初始化菇肃。
效率:構造函數(shù)之前執(zhí)行默認初始化。而成員初始化列表取募,可以立即初始化琐谤,所以更快些。
成員是const對象和引用必須初始化玩敏。
31.虛繼承
為了避免一個類多次集成一個基類而包含多份基類的拷貝斗忌,使用虛繼承機制。(基于多重繼承)
32.函數(shù)調用過程(堆棧圖)