我知道由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