11:知識點1:理解變量的銷毀與其內存的釋放之間的關系:內置類型的指針在離開作用域時,本身會被銷毀,但是其指向的內存空間什么都不會發生,必須以顯式的delete進行釋放空間。智能指針在離開作用域時,本身也會被銷毀,并且計數器減一,當其計數器為0且只有一個智能指針指向該對象時,該對象的內存空間會被釋放。如若用智能指針的get()函數得到的一個內置指針來初始化一個臨時的智能指針,一旦該內置指針被釋放,指向的內存也會被釋放,原來的智能指針就會變成空指針
知識點2:永遠不要用get初始化另一個智能指針或是給智能指針賦值
此題:利用P的get()函數得到的內置指針來初始化一個臨時的智能指針,一旦調用結束,該臨時指針被銷毀,內置指針所指對象內存會被釋放,使得p變為空懸指針
12:知識點1:將一個新的指針賦給shared_ptr:利用reset()函數,會更新計數。
此題:p為普通的內置指針指向一個動態內存,sp為智能指針指向一個動態內存
(a):合法,處理sp指針所指向內容,賦值的方式傳遞參數,處理完畢后內存不會被釋放
(b):不合法,參數必須是智能指針int類型
(c):同上
(d):合法,處理完畢后內存會被釋放
13:刪除p之后,會導致p指向的內存被釋放,此時sp就會變成空懸指針,在sp指針被銷毀時,該塊內存會被二次delete,執行后產生錯誤:double free
14:知識點1:如果在new和delete之間發生了異常,且異常未被捕獲,則該內存就永遠不會被釋放!(非常危險?。?!),而智能指針只要離開作用域,計數器減一,則隨著智能指針被銷毀,該塊內存也會被釋放,這就說明在實際使用過程中應使用shared_ptr來防止內存泄漏
知識點2:正確的使用智能指針:
1:不使用相同的內置指針值初始化多個智能指針
2:不delete get()返回的指針
3:不使用get()初始化或reset另一個只能指針
4:當你使用的智能指針管理的資源布氏new分配的內存,記住傳遞一個刪除器
15:直接將刪除器函數修改即可
[](connection *p){ disconnect *p; }16:知識點1:unique_ptr擁有其所指向的對象,屬于一一對應關系,unique_ptr被銷毀時,其對象也會被銷毀,unique_ptr不支持拷貝和賦值,必須采用直接初始化的方式,當我們定義一個unique_ptr時,必須將其綁定到一個new返回的指針上
知識點2:可以使用release():放棄對指針的控制權,返回指針,并將其置為空,和reset():如果提供了內置指針q,令u指向這個對象,否則將u置空,將指針的所有權轉移,但并沒有釋放內存
知識點3:在unique_ptr快要被銷毀時,可以進行拷貝:返回unique_ptr指針,這是一種特殊的拷貝P473頁
出現的問題:一一對應的關系,其指向的對象是其類的私有成員
error C2248: “std::unique_ptr<_Ty>::unique_ptr”: 無法訪問 PRivate 成員(在“std::unique_ptr<_Ty>”類中聲明)17:
(a):不合法,ix不是new返回的指針
(b):同上
(c):不合法,unique_ptr必須采用直接初始化
(d):不合法,同(a)
(e):合法
(f):合法,但是p5被銷毀后,p2所指向的內存也會被銷毀,使得p2成為空懸指針
18:release()函數的作用就是放棄對指針指向對象的控制權,但shared_ptr是多對一的關系,其他的智能指針仍然可以刪除這個對象,所以這個函數的話對shared_ptr沒意義
19:知識點1:weak_ptr:不控制所指向對象生命周期的智能指針,使用時必須進行判斷對象是否存在
shared_ptr<int> u(new int(1024));weak_ptr<int> w_ptr(u);if (shared_ptr<int> u = w_ptr.lock()){ //....}若weak_ptr指向的內容存在,則lock()返回一個指向共享對象的shared_ptr,若無,則返回空shared_ptr
這樣的類定義應該放在頭文件中
class StrBlob{public: friend class StrBlobPtr;//聲明friend StrBlobPtr begin(); StrBlobPtr end(); StrBlob();//默認構造函數 StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}///C++11新特性 StrBlob(string il):data(make_shared<vector<string>> (il)){}//另一構造函數 typedef vector<string>::size_type size_type;//定義類型別名,方便使用 //定義函數,返回大小 size_type size() const { return data->size(); } //判斷vector<string>是否為空 bool empty() { return data->empty(); } //向vector<string>中加入元素 void pushback(const string &s) { data->push_back(s); } //訪問函數,應首先調用check() string& front() { check(0,"front on empty StrBlob"); return data->front(); } string& back() { check(0,"back on empty StrBlob"); return data->back(); } void popback() { check(0,"pop_back on empty StrBlob"); data->pop_back(); }private: shared_ptr<vector<string>> data;//指向vector<string>的智能指針 void check(size_type i,const string &msg) const//若訪問元素的大小大于data的size,輸出錯誤信息 { if (i > data->size()) { throw out_of_range(msg);//拋出該out_of_range異常,表示不在范圍之內 } }};class StrBlobPtr{public: StrBlobPtr():curr(0){}//構造函數,將curr設定為0 StrBlobPtr(StrBlob &a, size_t sz = 0):wptr(a.data),curr(sz){}//構造函數,將StrBlob的智能指針與此類中的weak_ptr綁定 string& deref() const { auto p =check(curr,"deference past end"); return (*p)[curr]; } StrBlobPtr& incr() { auto p =check(curr,"deference past end"); ++curr; return *this; }private: shared_ptr<vector<string>> check(size_t i,const string& msg) const//檢查函數,返回一個vector<string>的智能指針 { auto ret = wptr.lock();//檢查對象是否還存在 if(!ret) { throw runtime_error("未綁定"); } if (i >= ret->size()) { throw out_of_range(msg); } return ret; } weak_ptr<vector<string>> wptr;//定義弱智能指針 size_t curr;//設立游標,表示下標};StrBlobPtr StrBlob::begin(){ return StrBlobPtr(*this);}StrBlobPtr StrBlob::end(){ return StrBlobPtr(*this, data->size());}20:
#include<iostream> #include<string> #include<fstream>#include<list>#include<vector> #include<map> #include<set>#include<cctype>//ctype無法打開,包含tolower()函數和ispunct函數#include<algorithm>#include<utility>//保存pair的頭文件#include<Chapter12.h>using namespace std;int main(int argc, char**argv) { ifstream in("1.txt"); string s; StrBlob blob; while (getline(in,s)) { blob.pushback(s); } for (StrBlobPtr pbeg(blob.begin()), pend(blob.end()); pbeg != pend; pbeg.incr()) cout << pbeg.deref() << std::endl; return 0;}
新聞熱點
疑難解答
圖片精選