c++ l理解智慧指標
阿新 • • 發佈:2022-12-10
智慧指標概述
C++的指標包括原始指標和智慧指標兩種,智慧指標是原始指標的封裝,其優點是可以自動分配記憶體,無需擔心記憶體的洩露。
並不是所有的指標都可以封裝為智慧指標,很多時候原始指標要更方便;
各種指標裡,原始指標最常用,其次是unique_ptr和shared_ptr,weak_ptr是對shared_ptr的補充,應用場景較少。
智慧指標只能解決一部分問題:獨佔/共享所有權指標的釋放和傳輸;並沒有從根本上解決C++的記憶體洩漏問題
獨佔指標 unique_ptr
在給定的時刻,只能有一個指標管理記憶體,當指標超出作用域後,記憶體自動釋放
該型別指標不可Copy,只可以Move
uniqueptr是智慧指標的一種,主要用於C++的記憶體申請和釋放,因為C++在申請記憶體後,要手動進行delete,這樣就會出現有時候忘記delete,或者return,break,異常等原因沒有執行到delete,不知道什麼時候delete記憶體,所以引入uniqueptr指標,當指標銷燬不時,自動刪除指標指向的記憶體。unique_ptr的特點是隻允許一個指標指向這塊記憶體,unique_ptr賦值操作是不允許的,例如uniqueptr1=uniqueptr2;是不允許的,只能通過轉移,uniqueptr1=move(uniqueptr2);將uniqueptr2指向的記憶體轉移給uniqueptr1。
建立方式
(1)通過已有的裸指標建立(建議裸指標設為空,並且及時銷燬,不推薦)
示例:
#include <stdio.h> #include <iostream> #include <algorithm> #include <vector> #include<Windows.h> using namespace std; //自定義資料型別 class Person { public: Person(string name, int age) { mName = name; mAge= age; } Person(); void Set_Name(string name) { this->mName = name; } void Info() { std::cout << "name:" << this->mName << endl; } public: string mName; int mAge; }; int main() { Person* p1 = new Person(); unique_ptr<Person> uc1{ p1 }; p1->Set_Name("哈哈"); uc1->Info(); // 這種方式需要再刪除裸指標 delete p1; p1 = nullptr; uc1->Info(); system("pause"); return 0; } Person::Person() { }
(2)通過new建立
示例:
#include <stdio.h> #include <iostream> #include <algorithm> #include <vector> #include<Windows.h> using namespace std; //自定義資料型別 class Person { public: Person(string name, int age) { mName = name; mAge = age; } Person(); void Set_Name(string name) { this->mName = name; } void Info() { std::cout << "name:" << this->mName << endl; } public: string mName; int mAge; }; int main() { unique_ptr<Person> uc2(new Person); uc2->mAge = 11; uc2->mName = "uc2"; uc2->Info(); system("pause"); return 0; } Person::Person() { }
結果:
(3)通過std::make_unique建立(推薦)
示例:
#include <stdio.h> #include <iostream> #include <algorithm> #include <vector> #include<Windows.h> using namespace std; //自定義資料型別 class Person { public: Person(string name, int age) { mName = name; mAge = age; } Person(); void Set_Name(string name) { this->mName = name; } void Info() { std::cout << "name:" << this->mName << endl; } public: string mName; int mAge; }; int main() { unique_ptr<Person> uc2 =make_unique<Person>(); uc2->mAge = 11; uc2->mName = "uc2"; uc2->Info(); system("pause"); return 0; } Person::Person() { }
unique_str可以通過get獲取地址,
通過->呼叫成員函式,
通過* (解引用)