我对智能指针还是个新手,我不理解下面附的代码的结果。基本上,shared_ptr
对象的引用计数和原始指针本身在传递给另一个unique_ptr
对象后会发生变化。
代码是这样的。
typedef shared_ptr<int> sp;
class bar {
public:
const sp& x; // line 3: if change this line to "const sp x;" then it's fine
bar(const sp xx) : x(xx) {
cout << "bar: count=" << x.use_count() << "; addr=" << x.get() << endl;
}
void test() {
cout << "test: count=" << x.use_count() << "; addr=" << x.get() << endl;
}
};
int main() {
auto p = make_shared<int>(0);
auto b = make_unique<bar>(p);
b->test();
}
如果我编译并运行代码,它会打印出:
bar: count=2; addr=0x557c8b02dec0
test: count=1224736736; addr=0x7ffdb5cbd5c0
所以引用计数和指针都改变了,看起来像是一些未初始化的值。
但是如果我把第3行改成const sp x;
,那么两个值看起来都正常:
bar: count=3; addr=0x5590f026eec0
test: count=2; addr=0x5590f026eec0
很抱歉使用了错误的命名,因为这是我为解决我的问题而提出的一个快速的最小情况。我觉得这与unique_ptr
的工作原理有关,但我不确定。
有人能给我一些启发,帮助我理解为什么代码会这样吗?
谢谢
1条答案
按热度按时间c9qzyr3d1#
此处:
将共享指针赋给一个局部变量
xx
,然后将常量引用x
绑定到 * that * 局部变量,当构造函数结束运行时,该局部变量将超出作用域,留下对Eldritch Horrors的引用和未定义的行为。要解释您关于删除
&
的观察结果:删除
&
可以防止这种情况发生,因为在这种情况下,您只需将共享指针直接赋给x
,x
从此不再依赖于局部变量xx
,因此不会受到其超出范围的影响。扩展:如果你想保存一个引用,你可以做的另一件事是将
xx
设置为引用本身(即bar(const sp& xx) : x(xx)
);在本例中,您将绑定x
到p
。