1:知識點1:對象生命周期:全局對象在程序啟動時分配,在程序結束時銷毀。局部自動對象,當我們進入其定義所在程序塊時被創建,在離開塊時被銷毀。局部static對象在第一次使用前分配,在程序結束時銷毀
知識點2:除了static和自動對象外,C++還支持動態對象的分配。動態分配的對象的生存期與它們在哪里創建無關,只有被顯示的釋放時,這些對象才會被銷毀
知識點3:動態對象的釋放是編程中極其容易出問題的地方,為了安全使用動態對象,標準庫定義了兩個智能指針類型來管理動態分配對象,當一個對象應該被釋放時,指向它的智能指針可以確保自動釋放它
知識點4:靜態內存:保存局部static對象、類static對象、定義在任何函數之外的對象,由編譯器自動創建和銷毀。棧內存:保存定義在函數之內的非static對象,棧對象僅在定義的程序塊運行時才存在
知識點5:除了靜態內存和棧內存,每個程序還擁有一個內存池,這部分內存被稱為自由空間或堆,程序用堆來存儲動態分配的對象:在程序運行時分配的對象,其生存周期由程序來控制,也就是說,當動態對象不再使用時,我們必須顯式的銷毀:必須正確的管理動態內存
知識點6:C++中動態內存的管理是通過一對運算符來完成的,new:在動態內存中為對象分配空間并返回一個指向該對象的指針。delete:接受一個動態對象的指針,銷毀該對象,并釋放與之關聯的內存
知識點7:忘記釋放內存:內存泄漏,在尚有指針引用內存的情況下釋放了內存,就會產生引用非法內存的指針
知識點8:為了更安全的使用動態內存,新標準庫定義了兩種智能指針類型來管理動態對象,頭文件為memory,智能指針的主要作用就是自動釋放所指向的對象,shared_ptr類型允許多個指針指向同一對象,unique_ptr類型則獨占所指向對象
知識點9:智能指針類似與vector,用法上有相同的地方,下面是shared_ptr的定義方式
shared_ptr<string> p1;//定義一個智能指針,指向對象為string類型shared_ptr<list<int>> p2;vector<string> p1;//智能指針也是模版vector<list<int>> p2;知識點10:智能指針的使用方式與內置類型指針相似,解引用也是返回所指向對象,若在條件判斷中使用,檢測其是否為空
知識點11:make_shared()函數:最安全的分配和使用動態內存的方法,此函數在動態內存中分配一個對象并初始化它,返回指向該對象的shared_ptr,頭文件為memory
shared_ptr<int> p3 = make_shared<int>(42);//p3為智能指針,指向一個值為42的對象auto p3 = make_shared<int>(42);//利用auto比較簡便,若不傳遞任何參數,會值初始化知識點12:每個shared_ptr都有一個關聯的計數器,稱為引用計數,個人理解就是該對象被引用的次數,拷貝情況下會遞增:
1:用一個shared_ptr初始化另一個shared_ptr(拷貝)
2:將一個shared_ptr傳遞給一個函數當參數,值傳遞(拷貝)
3:作為函數的返回值,(返回的是自身的拷貝,也就是活引用的次數+1)
計數器遞減情況:
1:給shared_ptr賦予一個新值(也就是說自身指向了另外一個地址,原來指向的對象已經沒有引用者,則會自動釋放)
2:一個shared_ptr離開其作用域時,會被銷毀(遞減)
當一個shared_ptr的計數器變為0,他就會自動釋放自己所管理的對象,前提是其指向的對象只有一個引用者。
知識點13:當指向一個對象的最后一個shared_ptr被銷毀時,該對象會被自動銷毀:利用析構函數,會遞減該對象的引用計數,當引用次數變為0,會銷毀該對象
知識點14:相關聯內存是否銷毀:所有指向該內存的shared_ptr對象都被銷毀,也就是計數器為0
知識點15:使用動態內存的原因:讓多個對象共享相同的底層數據。也就是說拷貝的情況雖然發生,但是并不是元素的拷貝,而是將本身的指向拷貝給另一個指針對象,讓這一個對象也指向自己所指向的對象,這樣在本身釋放以后,還有另一個對象指向自身原來所指向的對象。
由知識點15:b1和b2都包含4個元素。
2:直接在函數返回類型之前加const即可~
3:是否要定義為const版本取決于是否需要加以修改,這兩個函數都不會對參數進行修改,所以無需加const
4:因為data_size的類型為size_type,是一個無符號類型,即使是負數,也會自動轉化為非負。
5:explicit的作用就是抑制構造函數的隱式轉換
優點:不會自動的進行類型轉換,必須清楚的知道類類型
缺點:必須用構造函數顯示創建一個對象,不夠方便簡單
6:知識點1:new和delete相對于智能指針來說非常容易出錯,最好使用智能指針來管理動態內存
知識點2:在自由空間分配的內存是無名的,因此new無法為其分配對象命名,而是返回指向該對象的指針
知識點3:默認情況下,new分配的對象是默認初始化的,這就說明內置類型或者組合類型將是為定義的(l例如:int,會指向一個為初始化的int),類類型對象將用默認構造函數進行初始化(例如string,會產生一個空string)。
知識點4:建議使用值初始化(在最后加一對小括號即可),值初始化的內置類型對象有著良好定義的值
知識點5:auto只有單一參數時可以使用,可以使用new分配const對象
知識點6:delete完成兩個操作:銷毀給定指針所指向的對象,釋放對應的內存,delete的參數必須是指向動態分配的對象或是一個空指針。
知識點7:內置類型指針管理的動態內存在被顯式的釋放前一直都會存在,因為內置類型與類類型不同,雖然內置類型的指針會在離開作用域后被銷毀,但是其內存依然存在
知識點8:同一塊內存釋放兩次:兩個內置類型的指針指向同一塊自由空間分配的內存,在對一個指針進行delete之后,其指向的內存也會被釋放,若再對第二個指針進行delete,會造成自由空間破壞
知識點9:忘記使用delete,使用已經釋放掉的對象都是經常發生的(使用new和delete時),所以盡可能的使用智能指針
知識點10:在很多機器上,即使delete了某個內置類型的指針(也就是說釋放了對應的內存空間),雖然指針已經無效,但是其仍然保留這釋放空間的對應地址,變成了空懸指針,也就是說我們要保留指針,可以將其置為空指針
7:智能指針的版本只是不需要在程序結束時進行delete操作
#include <iostream> #include <string> #include <vector>#include<memory>#include<list>using namespace std; //返回一個動態分配的vector,看第六題的意思是不用只能指針,那么將類型改為vector<int> *就好了shared_ptr<vector<int>> vector_i(){ shared_ptr<vector<int>> _ptr(new vector<int>); return _ptr;}//給vector賦值void vector_j(shared_ptr<vector<int>> _ptr){ int int_val; while (cin>>int_val) { _ptr->push_back(int_val); }}//打印vector的值void vector_k(shared_ptr<vector<int>> _ptr){ for (size_t i = 0; i < (*_ptr).size(); ++i) { cout<<(*_ptr)[i]<<endl; }}int main(int argc,char **argv) { shared_ptr<vector<int>> my_ptr = vector_i(); vector_j(my_ptr); vector_k(my_ptr); return 0;}8:p是一個內置類型的指針,返回p會使得p的類型轉化為bool類型,其指向的動態內存空間將無法得到釋放
9:q,r為內置類型指針,保存動態內存的地址,進行二次賦值之后,r原來指向的內存空間將得不到釋放,造成內存泄漏
q2,r2為智能指針,r2進行賦值之后,其計數器將減一,由于r2是指向該內存空間的唯一智能指針,所以該內存會得到釋放
10:正確無誤
新聞熱點
疑難解答
圖片精選