*
和 ->
。以下範例建立了一個由共用指標管理的動態分配整數,然後即可通過該指標存取它:int main() { shared_ptr<int> p(new int); *p = 45; cout << *p + 1; return 0; }該程式碼將列印值 46。
class Person { string name; int age; public: string to_string() { return name + "" + to_string(age) + "n"; } //建構函式 Person () { name = " ";age = 0;} Person(const strings name, int age) { this->name = name; this->age = age; } }現在可以建立 2 個共用指標,每一個都可以管理不同的物件,就像下面這樣;
shared_ptr<Person> p1(new Person());
shared_ptr<Person> p2 (new Person ("Maria Wu", 23));
shared_ptr<Person> p1 = shared_ptr<Person>(new Person ());
shared_ptr<Person> p2 = shared_ptr<Person>(new Person("Maria Wu", 23));
T * rPtr = new T();
shared_ptr<T> sPtr1(rPtr);
shared_ptr<T> sPtr2 = sPtr1;
則 sPtr2 將變成和 sPtr1 同組的成員,共用 rPtr 物件的所有權,並且該組的參照計數也會增加 1。如果在此之後,sPtr2 被賦給了其他共用指標的值:sPtr2 = sPtr3;
則 sPtr2 將放棄 rPtr 的所有權,離開 sPtr1 的組,轉而加入 sPtr3 的組。第一個組(sPtr1 所在的組)的參照計數將減去 1,而第二個組(sPtr3 所在的組)的參照計數則增加 1。T * rPtr = new T(); shared_ptr<T> sPtr1(rPtr); shared_ptr<T> sPtr2(rPtr);這兩個共用指標指向兩個不同的控制塊,但控制塊管理的卻是相同的物件。如果第一個組的參照計數降至 0 並刪除該物件,那麼這將導致其他組的指標變成懸掛指標。為了避免出現這種問題,給定的裸指標應該最多只能初始化一個共用指標。
shared_ptr<Person> p1(new Person());
該語句的執行涉及兩個獨立的記憶體分配:一個分配控制塊,第二個則分配記憶體給被管理的 Person 物件。每個記憶體分配都會產生相當一部分開銷,所以,更高效的做法是,分配一個足夠大的記憶體塊,以同時儲存控制塊和被管理的物件。make_shared<T>()
使用該函數即可將上述共用指標建立語句改寫為以下形式:shared_ptr<Person> p1 = make_shared<Person>();
該版本的 make_Shared 語句可以使用預設建構函式初始化被管理的物件。shared_ptr<Person> p2 (new Person ("Maria Wu", 23));
該語句可以被改寫為以下形式:shared_ptr<Person> p2 = make_shared<Person>("Maria Wu", 23);
推薦使用 make_shared 函數方式建立共用指標。除了更高效之外,它還無須直接處理裸指標,因此也消除了雙重管理的可能性。成員函數 | 描 述 |
---|---|
T* get() | 返回指向被管理物件的裸指標,如果沒有被管理的物件,則返回空指標 |
void reset() | 釋放任何可能存在的被管理物件的所有權。呼叫的共用指標被置為空 |
void reset(T* ptr) | 釋放當前被管理的物件的所有權。獲取由 ptr 指向的物件的所有權 |
long use_count() | 返回參照相同的被管理物件的共用指標數量 |
shared_ptr<T> p =....; if ( P ) { //被管理的物件 } else { //共用指標為空 }
shared_ptr<T[ ] > sPtr; // 錯誤
不能使用以上語句指定被管理的物件型別為陣列。有一種簡單方法可以繞過這種限制,那就是使用指向 T 型別向量的共用指標:shared_ptr<vector<T>> sVecPtr;
當向量被銷毀時,其解構函式將執行並銷毀所有的向量元素。