boost::shared_ptr来自指针

boost::shared_ptr from pointer

本文关键字:指针 shared boost ptr      更新时间:2023-10-16

我刚刚偶然发现了boost::shared_ptr文档,它是:

Sometimes it is necessary to obtain a shared_ptr given a raw pointer
to an object that is already managed by another shared_ptr instance.
Example:
void f(X * p) 
{
shared_ptr<X> px(???);
}
Inside f, we'd like to create a shared_ptr to *p.
In the general case, this problem has no solution.

为什么?是不是不允许做这样的事情:

shared_ptr<X> px(p);

我是不是错过了什么?

如果有一个shared_ptr管理一个指针,然后创建另一个shared-ptr管理同一指针(而不是复制原始的shared_ptr),那么同一资源最终会有两个管理器。当两者中的一个达到引用计数0时,它将删除对象,而另一个shared_ptr将指向已删除的内存。

如果你想这样做:

main() {
Object *obj = new Object();
func(obj)
}
void func( Object *obj ) {
shared_ptr objPtr(obj); // take ownership.
objPtr->fun();
// Passed object "obj" is destroyed here.
}

在函数func结束时,对象指针将被销毁,而有了指针,对象本身也将被销毁。这不是一种可取的行为。

实际上,你可以这样做,但你必须知道,当退出函数时,指向的对象会被删除。。。

我尝试过助推:

void f(X * p)
{
boost::shared_ptr<X> px(p);
// do smething
}
void main()
{
X* ptr = new X();
f( ptr );
// ptr is not valid anymore because the object were deleted
}

Jean

你可以这样做,但这可能会导致未定义的行为,因为没有办法告诉第二个共享指针引用计数(指向同一对象的共享指针数量)增加了。然后可能会发生这样的事情:

void f()
{
boost::shared_ptr<int> firstSmart(new int(23)); // firstSmart is the only 
// manager of the int
int *raw = firstSmart.get();
boost::shared_ptr<int> secondSmart(raw);        // secondSmart also manages
// the same int as firstSmart
// but secondSmart does not 
// know about firstSmart
// and vice versa
}

f退出时,secondSmart被销毁,销毁共享的int。然后firstSmart被销毁并试图销毁已经销毁的int,从而导致未定义的行为。

这是不可能的。

共享指针使用引用计数工作。将资源(原始指针)分配给共享指针时,将创建一个引用计数对象,计数为1。当为同一资源创建另一个共享指针时,引用计数对象(在两个共享指针之间共享)被更新为值count=2。如果删除了一个共享指针,则共享引用对象中的计数将递减,当指针达到0时,资源将被销毁。

为了使上述机制发挥作用,应该使用shared_ptr px(p)之类的东西创建第一个共享指针,并使用px(而不是"p")创建所有后续指针。通过这种方式,所有创建的共享指针都将知道它们持有相同的资源并共享相同的引用计数对象。

如果您使用shared_ptr-px(p)创建了另一个共享指针,那么您最终会得到两个彼此不相关的共享指针,即引用计数对象不相同。它们都假设它们持有不同的资源,并且每个都有不同(不同)的引用计数对象,计数为1。(你不想要这个)。