1. 繼承關系下,析構函數和構造函數執行順序?
構造函數按照依賴鏈,從強到弱構造
首先調用基類的構造函數。如果有多個基類,則按照它們在派生類聲明中出現的順序調用;接下來,按照它們在類中聲明的順序,調用派生類中所有非靜態成員變量(包括從基類繼承的成員變量)的構造函數;最后調用派生類自己的構造函數體。這意味著,派生類的構造函數有機會使用已經初始化完畢的基類成員和派生類成員。
析構函數按照依賴鏈,從弱往強進行析構
首先執行派生類的析構函數體;然后按照它們在類中聲明的逆序,調用派生類中所有非靜態成員變量的析構函數;最后調用基類的析構函數;如果有多個基類,同樣按照它們在派生類聲明中逆序調用。
2. 虛函數表和虛函數表指針的創建時機
編譯器發現類中包含 virtual 關鍵字修飾的函數就會創建虛函數表。虛函數表的內容在編譯的時候就已經生成了。虛函數表存儲在全局數據區的只讀數據字段中,虛函數表是存放虛函數的地址的數組。
當一個包含虛函數的類的對象被創建時,編譯器會確保在對象的內存布局中包含一個指向虛函數表的指針,即vptr。vptr
的初始化(即賦值為虛函數表的地址)通常發生在對象構造函數執行的過程中。即使沒有顯示定義構造函數,編譯器也會自動生成一個默認構造函數來完成這項任務。
在繼承關系中,調用基類構造函數的時候,先將基類的虛函數表地址賦值給 vptr,接著調用子類構造函數的時候,又將子類的虛函數表地址賦值給 vptr。
3. 虛析構函數的作用
虛析構函數是在C++中,為了實現多態性而在基類中聲明為虛函數的析構函數。
在繼承下,為了使子類析構函數能得到正常調用,需要將基類的析構函數設置為虛析構函數。
設置虛析構函數是有代價的,編譯器會為類生成虛函數表,每個對象都需要持有 vptr
4. 手動管理指針可能出現哪些問題?
野指針:指向了一個未知的、無效的或者未初始化的地址
指針懸掛:釋放了內存但是忘記把指針置空
踩內存:程序在運行過程中發生了越界
沒有釋放資源產生內存泄漏,重復釋放資源引發coredump
5. C++智能指針的原理
unique_ptr:?代表獨占所有權的智能指針。它保證同一時間內只有一個unique_ptr
實例擁有指向對象的指針。當unique_ptr
離開作用域時,它會自動刪除所擁有的對象,從而釋放內存
shared_ptr: 引用計數,允許多個智能指針共享同一個對象的所有權。它通過引用計數機制工作,即一個控制塊(通常是一個原子計數器)記錄有多少個shared_ptr
指向同一塊內存。當最后一個指向該內存的shared_ptr
銷毀時,引用計數減至零,此時控制塊會自動釋放這塊內存。
weak_ptr:?一種不增加引用計數的智能指針,它用于非擁有地觀察由一個或多個shared_ptr
管理的對象。主要用于解決循環引用的問題,因為weak_ptr
不會增加被觀察對象的引用計數,即使持有weak_ptr
的實例很多,也不會阻止對象被銷毀。
6. 靜態庫和動態庫的區別
(1)鏈接方式:靜態鏈接把靜態庫編譯到目標文件;動態鏈接沒有把庫編譯到目標文件,而是在程序運行時才去加載代碼
(2)空間占用:靜態庫會存在多個副本,動態庫只有一個副本
(3)使用方式:靜態庫 程序直接運行,動態庫需要根據指定的路徑查找動態庫
(4)執行速度:動態庫執行慢,靜態庫執行速度較快
(5)庫文件發生變更:接口變更都需要重新編譯,接口實現改變如果是動態鏈接只需要重新編譯動態庫。
7. 使用過C++11哪些新特性
新的語法糖:auto, decltype, nullptr, final, override, const, 基于范圍的for循環,function函數對象
?STL容器:vector、list、unordered_ma、unordered_set
智能指針:shared_ptr, weak_ptr, unique_ptr
多線程:thread、mutex、lock_guard、condition_variable、atomic
右值引用:T &&;實現移動語義和完美轉發
8. 左值引用和右值引用的區別?右值引用的意義?
左值可以在等號左邊,能夠取地址,有一個具體的名字,右值只能在等號右邊,不能取地址,不具名。
左值常見例子:變量名,返回左值引用的函數調用,前置自增自減,解引用表達式
右值常見例子:字面值,返回非引用類型的函數調用,后置自增自減,算數表達式,邏輯表達式,比較表達式,將亡值
右值引用的意義:避免資源的復制,實現資源所有權的轉移,在模板編程中,右值引用和模板參數的結合使用可以實現完美轉發(perfect forwarding),允許將函數參數以原始類型(左值或右值)轉發給其他函數。
10. 什么是將亡值?
指的是即將被銷毀的對象。這個概念是在C++11標準中引入的,用于描述那些即將被移動(move)操作所消費的對象。移動操作是一種優化技術,它允許將資源(如內存、文件句柄等)從一個對象轉移到另一個對象,而無需復制這些資源。
這是一條吃飯博客,由挨踢零聲贊助。學C/C++就找挨踢零聲,加入挨踢零聲,面試不挨踢!