C Primer 讀書筆記04

2021-10-25 18:43:58 字數 4385 閱讀 9285

智慧型指標

直接管理記憶體

unique_ptr

weak_ptr

lock

動態陣列

「c++ primer」

關聯容器

標準庫提供 8 個關聯容器,他們的不同體現在:

或者是乙個set,或者是乙個map或者要求不重複的關鍵字,或者允許重複關鍵字,允許重複關鍵字的容器的名字中都包含單詞multi按順序儲存或者無序儲存,不保持關鍵字按順序儲存的容器的名字都以unordered開頭

pair

定義在標頭檔案utility中,pair是乙個用來生成特定型別的模板,當建立乙個pair時,必須提供兩個型別名

pair的資料成員是public的,兩個資料成員分別是firstsecond

動態記憶體

靜態記憶體

靜態記憶體用來儲存區域性static物件、類static資料成員以及定義在任何函式外的變數,由編譯器自動分配和銷毀,static物件在使用之前分配, 在程式結束時銷毀

棧記憶體用來儲存定義在函式內的非static物件,由編譯器自動分配和銷毀,僅在其定義的程式塊執行時才存在

智慧型指標

與常規指標的區別:負責自動釋放所指向的物件

shared_ptr

make_shared()函式:最安全的分配和使用動態記憶體的方法

shared_ptrp3 = make_shared(42);	// 指向乙個值為 42 的 int 的 shared_ptr
shared_ptr的拷貝和賦值

每個shared_ptr都有乙個關聯的計數器,稱為引用計數,無論何時我們拷貝乙個shared_ptr,計數器都會遞增,如用乙個shared_ptr初始化另乙個shared_ptr,或將它作為引數傳遞給乙個函式以及作為函式的返回值;當給shared_ptr賦乙個新值或是shared_ptr被銷毀,計數器遞減

一旦乙個shared_ptr的計數器變為 0 ,它就會自動釋放自己管理的物件

shared_ptr的析構函式會遞減它所指的物件的引用計數,如果引用計數變為0,shared_ptr的析構函式就會銷毀物件,並釋放記憶體

直接管理記憶體

new預設情況下,動態分配的物件是預設初始化的,內建型別或組合型別的物件的值是未定義的,類型別物件將使用預設建構函式進行初始化

int *pi = new int;	// pi 指向乙個動態分配的,為初始化的無名物件

int *pi2 = new int(); // 值初始化為 0,*pi2 為0

string *ps = new string; // 初始化為空的 string

值初始化的內建型別物件有著良好定義的值,而預設初始化的物件的值則是未定義的

空懸指標

指向一塊曾經儲存資料物件但現在已經無效的記憶體的指標

智慧型指標陷阱

不使用相同的內建指標值初始化(或 reset)多個智慧型指標

delete get()返回的指標

不使用get()初始化或reset另乙個智慧型指標

如果使用get()返回的指標,記住當最後乙個對應的智慧型指標銷毀後,你的指標就變為無效了

如果使用智慧型指標管理的資源不是new分配的記憶體,記住給它傳遞乙個刪除器

unique_ptr

乙個unique_ptr擁有它所指向的物件,與shared_ptr不同,某個時刻只能有乙個shared_ptr指向乙個給定物件,也沒有make_shared這樣的標準庫函式,當定義乙個unique_ptr時,需要將其繫結到乙個new返回的指標上,初始化unique_ptr必須採用直接初始化形式

unique_ptrpl;

unique_ptrp2(new int(42));

unique_ptrp3(new string("test"));

unique_ptrp4(p3); // 錯誤,unique_ptr 不支援拷貝

unique_ptrp5;

p5 = p3; // 錯誤,unique_ptr 不支援賦值

unique_ptrp6(p3.release()); // 將所有權從 p3 轉移給 p6, release 將 p3 置為空

unique_ptrp7(new string("test"));

p4.reset(p7.release()); // 將所有權從 p7 轉移給 p4, release 將 p3 置為空,並返回指標,p4 釋放原來指向的記憶體

release()會切斷unique_ptr和它原來管理的物件間的聯絡,如果不使用另乙個智慧型指標儲存release()返回的指標,我們就要負責資源的釋放

p2.release();	// 錯誤, p2 不會釋放記憶體,而且我們丟失了指標

auto p = p2.release(); // 正確,但必須記得 delete(p)

不能拷貝unique_ptr規則例外:我們可以拷貝或賦值乙個將要被銷毀的unique_ptr

unique_ptrclone(int p)
weak_ptr

weak_ptr是一種不控制所指向物件生存週期的智慧型指標,它指向由乙個shared_ptr管理的物件,將乙個weak_ptr繫結到shared_ptr不會改變shared_ptr的引用計數

由於物件可能不存在,不能直接使用weak_ptr訪問物件,必須呼叫lock

lock

此函式檢查weak_ptr指向的物件是否存在,如果存在,返回乙個指向共享物件的shared_ptr

動態陣列

new和陣列

int *pia = new int[get_size()];	// 方括號中必須是整型但不必是常量
new返回的是乙個元素型別的指標,分配的記憶體並不是乙個陣列型別,因此不能對動態陣列呼叫beginend,也不能使用範圍for語句

智慧型指標與動態陣列

標準庫提供了乙個可以管理new分配的陣列的unique_ptr版本,使用時需要在物件型別後加上一對空方括號

unique_ptrup(new int[10]);	// up 指向乙個包含 10 個為初始化 int 的陣列

allocator

new將記憶體分配和物件構造組合在了一起,標準庫allocator類定義在標頭檔案memory中,它幫助我們將在記憶體分配和物件構造分離開來,它分配的記憶體是原始的、未構造的

allocatoralloc;	// 可以分配 string 的 allocator 物件

auto const p = alloc.allocate(n); // 分配 n 個未初始化的 string

auto q = p; // q 指向最後構造的元素之後的位置

alloc.construct(q++); // *q 為空字串

alloc.construct(q++, 10, 'c'); // *q 為 cccccccccc

while(q != p)

alloc.destroy(--q); // 釋放構造的 string

alloc.deallocate(p, n); // 釋放記憶體

C primer 讀書筆記

第2 章 變數和基本型別 1 變數直接初始化和變數 複製初始化 int ival 1024 direct initialization int ival 1024 copy initialization 初始化不是賦值 2 內建型別復 制初始化和直接初始化幾乎沒有區別 但 對類型別物件來 說,有些初...

C Primer讀書筆記

前些日子開始看 c primer 順便做一些筆記,既有書上的,也有自己理解的。因為剛學c 不久,筆下難免有謬誤之處,行文更是凌亂 所幸不是用來顯配的東西,發在linuxsir只是為了方便自己閱讀記憶,以防只顧上網忘了正事。書看了不到一半,所以大約才寫了一半,慢慢補充。const要注意的問題 1 下面...

C Primer讀書筆記

前些日子開始看 c primer 順便做一些筆記,既有書上的,也有自己理解的。因為剛學c 不久,筆下難免有謬誤之處,行文更是凌亂 所幸不是用來顯配的東西,發在linuxsir只是為了方便自己閱讀記憶,以防只顧上網忘了正事。書看了不到一半,所以大約才寫了一半,慢慢補充。const要注意的問題 1 下面...