本基本知識整理及代碼源於牛客網C++面試寶典導讀,
網址https://www.nowcoder.com/tutorial/93/7047559bae6c461582560f58175faa45
STL基本組成
容器、迭代器、分配器、算法、仿函數、配接器。
分配器給容器分配內存空間,算法通過迭代器獲取容器中內容,仿函數協助算法完成各種操作,配接器用來套接適配仿函數。
vector和list
vector:
連續存儲容器,動態數組,在堆上分配空間。
底層實現:數組。
兩倍容量增長:
插入新元素時,如果超過容量,則會重新分配原有個數的兩倍空間,將原空間元素賦值到新空間再增加新元素,最后析構並釋放原空間,之前的迭代器失效。
適用:隨機訪問,不常在非尾節點插入刪除。
List:
動態鏈表,在堆上分配空間。插入和刪除都會分配或釋放空間。
底層實現:雙向鏈表。
適用:不能隨機訪問,只能快速訪問頭尾節點。
resize和reserve區別
resize:改變容器內含有元素的數量(size()),可以縮小。
reserve:改變當前容器的最大容量(capicity()),不能縮小。
map和set
map和set都是關聯容器,底層實現都是紅黑樹。map和set的接口紅黑樹都提供了。
區別:
1. map是key-value(關鍵字-值):關鍵字起索引作用,值是和索引關聯的數據。set是關鍵字的集合。
2. set迭代器為const,不能修改元素的值(關鍵字不能修改);map可以修改value,不能修改key。map和set是根據關鍵字排序來保證其有序。修改key則應刪除鍵,調節平衡,再插入鍵,調節平衡,會破壞結構導致迭代器iterator失效。
3.map支持下標操作,set不支持下標操作。map使用key做下標去查找,如果key不存在,則插入該關鍵字和值到map中。只希望確定某一關鍵值是否存在則應該使用find。
迭代器
迭代器是類模板,重載了指針的操作符部分操作符,是一個可遍歷STL容器內全部或部分元素的對象,本質是封裝了原生指針,提供了比指針更高級的行為,相當於一種智能指針,可以根據不能類型的容器來實現不同的++,--等操作。
迭代器返回的是對象引用而不是值,cout智能輸出迭代器使用*解引用后的值。
迭代器訪問方式就是將不同集合類的訪問邏輯抽象出來,使得不用暴露內部結構而達到循環遍歷集合的效果。
STL的allocator
STL分配器用於封裝STL容器在內存管理上的底層細節。
alloc::allocate()負責分配內存,alloc::deallocate()釋放空間。對象構造由construct()負責,析構由destroy()負責。
采用兩級配置器,分配空間大小超過128b時使用第一級空間配置器,小於128b時第二級。第一級空間配置器使用malloc、realloc、free進行內存分配和釋放;第二級采用內存池計數,通過空閑鏈表來管理內存。
STL迭代器刪除元素失效
1.vector、deque,使用erase后,后面每個元素迭代器都會失效,后面每個元素向前移動一個位置,erase返回下一個有效迭代器。
2.map、set,使用erase后,當前迭代器失效,不會影響下一個元素迭代器,在調用erase前記錄下一個迭代器即可。
3.list不會失效,調用erase會返回下一個有效迭代器。
C++中類訪問權限
通過public、protected、private關鍵字來控制成員變量和成員函數的訪問權限。在類的內部都可以互相訪問。在類的外部,只能通過對象訪問public屬性成員,子類對象可以訪問public和protected成員。
C++中struct和class的區別
strct和class都可以定義類,但struct默認權限都是public,class則是private。
struct和class和union 內存
struct和class內存對齊,空類的大小為1。
類中有虛函數時,會有一個指向虛函數表的指針(vptr),32位系統下指針大小為4。
靜態數據成員是在全局/靜態區,不影響類的大小。
派生類則是基類大小加自身成員大小。
union共享內存,所以為最大成員變量的內存。
對齊:各數據類型對齊值不同:char對齊值為1,short為2,int float double為4。
結構體或類自身對齊值為成員中對齊值最大的那個值。
數據成員有效對齊值:自身對齊值和指定對齊值中小的那個值。
右值引用
右值指即將消散的值(臨時變量或即將析構的對象或匿名對象),右值引用則實現了轉移語義,將右值轉移到其他變量上。
主要目的:1.消除兩個對象交互時不必要的拷貝,提高效率(移動構造函數)
2.能夠更簡潔明確定義泛型函數。
C++源文件從文本到可執行文件經歷的過程
預處理階段:將源代碼中文件包含關系(頭文件)、預編譯語句進行分析和替換,生成預編譯文件。
編譯階段:將預處理過的預編譯文件轉換成特定匯編代碼,生成匯編文件。
匯編階段:將編譯階段生成的匯編文件轉換為機器滿,生成二進制可重定位文件。
鏈接階段:將多個目標文件及所需要的庫連接成最終可執行目標文件。
鏈接發生在編譯、程序被加載以及程序執行時,主要工作是符號解析和重定位
C++ 鏈接庫
庫分為兩種:靜態庫(.a、.lib) 動態庫(.so、.dll),動態靜態指鏈接過程。
lib在編譯時鏈接,而動態庫在運行時鏈接。
如果有dll文件,則lib記錄dll中函數入口和位置,dll則是函數具體內容。
include頭文件雙引號和尖括號的區別。
區別:編譯器預處理階段查找頭文件路徑不同。
使用雙引號查找順序:
當前頭文件目錄
編譯器設置的頭文件路徑
編譯器設置的頭文件路徑
使用尖括號則只包含后兩步。
STL里sort算法用的是什么排序算法?
先使用快排分段,數據量小於16則進行插入排序,遞歸程度深則使用堆排序。