您好,登錄后才能下訂單哦!
這篇文章主要介紹了C++智能指針使用實例分析的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇C++智能指針使用實例分析文章都會有所收獲,下面我們一起來看看吧。
程序運行時存在靜態空間、棧和堆區,用堆來存儲動態分配空間的對象即那些在程序運行時分配空間的對象,若該對象不再使用,我們必須顯式的銷毀它們,避免內存泄漏。
智能指針是一個可以像指針一樣工作的對象,有unique_ptr(獨占指針),shared_ptr與weak_ptr等智能指針,定義在<memory>頭文件中,可以對動態資源進行管理。
保證以構造的對象最終會銷毀,即它的析構函數最終會被調用。
注意:
1.為了避免內存泄漏,通過智能指針管理的對象應該沒有其他的引用指向它們.
2.智能指針不支持指針的算術運算
我們大多數場景下用到的都是unique_ptr。
其在默認情況下和普通指針的大小是相同,內存上沒有任何的額外消耗,性能最優。
注意:
1.不能使用其他unique_ptr對象的值來初始化一個unique_ptr。也不能將一個unique_ptr對象賦值給另外一個。這樣的操作將導致兩個獨占指針共享相同對象的所有權。
2.unique_ptr代表的是專屬所有權,如果想要把一個unique_ptr的內存交給另外一個unique_ptr對象管理。
只能使用std::move轉移當前對象的所有權。轉移之后,當前對象不再持有此內存,新的對象將獲得專屬所有權。
3.若unique_ptr指向的是一個對象數組的話,要確保調用delete[]來處理被解除分配的數組,則應該在對象類型后面包含一對空的方括號[]。
#include<iostream> #include<memory> using namespace std; int main() { unique_ptr<int> up1(new int(11)); cout << "up = " << *up1 << endl; //將up1的獨占權轉移給up2,up1不能再操作堆區空間 unique_ptr<int> up2 = std::move(up1); cout << "up2 = " << *up2 << endl; //up2.reset();//若為無參作用是顯示釋放堆區內容 up2.reset(new int(22));//若為有參,先釋放原來堆區內容,重新給up2綁定一個新的堆區內容 cout << "up2 = " << *up2 << endl; //釋放控制權,但不釋放堆區內存 int* p = up2.release(); cout <<"p = "<< *p << endl; delete p; p = nullptr; return 0; }
#include<iostream> #include<memory> using namespace std; int main() { //指向數組的獨占指針 unique_ptr<int[] > up(new int[5]); for (int k = 0; k < 5; k++) { up[k] = k+1; } for (int k = 0; k < 5; k++) { cout << up[k] << " "; } cout << endl; return 0; }
多個shared_ptr智能指針可以共同使用同一塊堆內存。由于該類型智能指針在實現上采用的是引用計數機制,
即便有一個shared_ptr指針放棄了堆內存的"使用權"(引用計數減1)也不會影響其他指向同一堆內存的shared_ptr指針(只有引用計數為0時,堆內存才會被自動釋放)
#include<iostream> #include<memory> using namespace std; int main() { shared_ptr<int> sp1(new int(11)); shared_ptr<int>sp2(sp1);//拷貝構造 cout << "num = " << sp2.use_count() << endl;//打印計數器 2 sp1.reset(); cout << "num = " << sp2.use_count() << endl;//1 cout << *sp2 << endl;//11 sp1.reset(); cout << "num = " << sp1.use_count() << endl;//0 return 0; }
shared_ptr的內存占用是裸指針的兩倍。因為除了要管理一個裸指針外,還要維護一個引用計數。 因此相比于unique_ptr, shared_ptr的內存占用更高。
該類型指針通常不單獨使用(沒有實際用處),只能和shared_ptr搭配使用。我們可以將weak_ptr視為shared_ptr指針的一種輔助工具。
借助weak_ptr類型指針,我們可以獲取shared_ptr指針的一些狀態信息,比如有多少指向相同的shared_ptr指針,shared_ptr指針指向的堆內存是否已經被釋放等。
當weak_ptr類型指針的指向和某一shared_ptr指針相同時,weak_ptr并不會使所指堆內存的引用計數加1
當weak_ptr指針被釋放時,之前所指堆內存的引用計數也不會因此而減1.也就是說,weak_ptr并不會影響所指堆內存空間的引用計數。
weak_ptr<T>模板類中沒有重載*和->運算符 , weak_ptr 類型指針只能訪問所指的堆內存,而無法修改它
#include<iostream> #include<memory> using namespace std; int main() { shared_ptr<int>sp1(new int(11)); shared_ptr<int>sp2(sp1); weak_ptr<int>wp = sp1; cout << wp.use_count() << endl; shared_ptr<int>sp3 = wp.lock(); //lock() 若當前weak_ptr已經過期,則該函數會返回一個空的shared_ptr指針.反之,該函數返回一個和當前weak_ptr指向相同的shared_ptr。 cout << wp.use_count() << endl; if (sp3 == nullptr) { cout << "堆區空間已經釋放" << endl; } else { //cout << *wp << endl;//err cout << *sp3 << endl;//間接訪問 } return 0; }
#include<iostream> using namespace std; class Person { public: Person(int age) { cout << "有參構造函數調用" << endl; m_age = age; } void showage() { cout << "年齡為:" << this->m_age << endl; } ~Person() {} int m_age; }; //利用智能指針管理new出來的內存的釋放 class Smartpoint { public: Smartpoint(Person* p) { this->m_person = p; } //重載->運算符 Person* operator->() { return this->m_person; } //重載*運算符 Person& operator*() { return *m_person; } ~Smartpoint() { if (this->m_person != NULL) { //cout << "析構函數調用" << endl; delete this->m_person; } } private: Person* m_person; }; int main() { Smartpoint sp(new Person(18)); sp->showage(); (*sp).showage(); return 0; }
關于“C++智能指針使用實例分析”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“C++智能指針使用實例分析”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。