我知道由std::shared_ptr
管理的對象不是delete
d由reset()
,除非它是管理它在該點的唯一shared_ptr
。我知道當有多個shared_ptr
管理同一個對象時,對被管理對象值的更改通過指向它的所有shared_ptr
s反映出來,而對這些shared_ptr
的值(而不是其管理對象的值)通過reset()
婷它引起的(即改變shared_ptr
從一個指向原來的管理對象,以一個指向什麼或別的東西),不改變其他shared_ptr
S'值(即它們都依然指向原來的管理對象,和原來的管理對象仍然存在):重置一個shared_ptr的嵌套智能指針到一個shared_ptr(或到的unique_ptr),看似矛盾
#include <memory>
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<shared_ptr<int>> vec{ make_shared<int>(5) };
shared_ptr<int> sptr(vec[0]);
++ *sptr;
cout << *vec[0] << endl; // 6
vec[0].reset();
vec.pop_back();
cout << *sptr << endl; // 6
}
但是,邏輯是使用兩個層次:○當我失去了聯繫f間接。給定一個名爲Wrapper
類和shared_ptr<shared_ptr<Wrapper>>
並初始化爲任意數量的其他shared_ptr<shared_ptr<Wrapper>>
S的前,爲什麼會發生這種配置允許reset()
呼籲任何內部shared_ptr
有效reset()
所有其他內shared_ptr
S'
我的猜測是:任何出 ER的shared_ptr
S中的管理對象是內shared_ptr
(不是Wrapper
)和改變的值的內shared_ptr
(由reset()
婷內shared_ptr
,其改變從一個指向一個Wrapper
實例,一個指向任何內部shared_ptr
的值)在所有出呃shared_ptr
S反射,有效地引起所有出呃shared_ptr
結束了在失去間接管理實例,從而刪除Wrapper
實例。
但是,同樣的邏輯,是不是復位內指針只會導致特定的內部指針在Wrapper
失去管理的一個?由於所有其他外部指針指向(構建與他們,即那些)自身的內部指針,將不是那些外的人繼續在Wrapper
有間接管理,因爲重置一個內部指針不改變Wrapper
的價值,這應該仍然可以訪問由其他內部指針?這對我來說是一個悖論。
如果重置一個內部指針有效地重置所有的內部指針,那麼意味着內部指針'use_count()
是1
正好在reset()
之前。只有這樣,我想多shared_ptr
S能出現,同時在1
保持use_count()
將通過錯覺管理相同的對象:他們管理不同的對象具有相同的值(在不同的地址,即對象)。我通過製作一個名稱爲Wrapper
的int
包裝來測試此功能,該包裝的唯一數據成員是包裝的int
和static
instance_count
,用於跟蹤當前存在的Wrapper
實例的數量。
struct Wrapper {
Wrapper(int par = 0) : num(par) { ++instance_count; }
Wrapper(const Wrapper& src) : num(src.num) { ++instance_count; }
~Wrapper() { --instance_count; }
int num;
static int instance_count;
};
int Wrapper::instance_count = 0;
int main() {
shared_ptr<shared_ptr<Wrapper>> dual_ptr_1(
make_shared<shared_ptr<Wrapper>>(
make_shared<Wrapper>(Wrapper(5))
)
);
// - Output -
cout << Wrapper::instance_count << endl; // 1
shared_ptr<shared_ptr<Wrapper>> dual_ptr_2(dual_ptr_1);
cout << Wrapper::instance_count << endl; // 1
cout << dual_ptr_1->use_count() << endl; // 1
cout << dual_ptr_2->use_count() << endl; // 1
cout << dual_ptr_1.use_count() << endl; // 2
cout << dual_ptr_2.use_count() << endl; // 2
// note that above, the '->' operator accesses
// inner ptr while '.' operator is for outer ptr
cout << (*dual_ptr_1)->num << endl; // 5
cout << (*dual_ptr_2)->num << endl; // 5
dual_ptr_2->reset();
cout << Wrapper::instance_count << endl; // 0
cout << dual_ptr_1->use_count() << endl; // 0
cout << dual_ptr_2->use_count() << endl; // 0
cout << dual_ptr_1.use_count() << endl; // 2
cout << dual_ptr_2.use_count() << endl; // 2
}
顯然有指向1
Wrapper
對象2
內的指針;內部指針'use_count
最多爲1
(銷燬前); Wrapper
類的instance_count
最多爲1
(破壞前);並且間接管理的對象可以通過兩個外部指針訪問(這意味着兩個外部指針都不會被其他指針移動構建)。並重置一個內部指針有效地重置所有這些;所以我仍然不明白這似乎是悖論。
我還問在這個崗位約在上面的代碼有內shared_ptr
S按unique_ptr
條取代的情況下同樣的問題,內make_shared
換成make_unique
和use_count()
註釋掉的內部指針(因爲unique_ptr
缺少該方法),它給出相同的輸出。這對我來說似乎是一個悖論,因爲unique_ptr
在這裏似乎並不獨特。
我不確定你的期望是什麼,'dual_ptr_1'和'dual_ptr_2'都共享單個內部'shared_ptr'的所有權,而後者又管理'Wrapper'的單個實例。 'dual_ptr_2-> reset();'銷燬單個'Wrapper'實例,這樣你就可以共享一個空的'shared_ptr'了。 – user657267 2014-11-05 02:30:42
正如其他人所說的。可以這樣想:'Wrapper * w = new Wrapper();包裝** a =&w;包裝** b =&w;刪除* a; * a = nullptr;'< - 您會驚訝現在'* b'現在爲空嗎? – cdhowie 2014-11-05 03:31:08