shared_ptr和循环引用

zer*_*int 9 c++ shared-ptr weak-ptr cyclic-reference

我正在尝试使用循环引用boost::shared_ptr,并设计了以下示例:

class A{ // Trivial class
public:
    i32 i;
    A(){}
    A(i32 a):i(a){}
    ~A(){
        cout<<"~A : "<<i<<endl;
    }
};

shared_ptr<A> changeI(shared_ptr<A> s){
    s->i++;
    cout<<s.use_count()<<'\n';

    return s;
}

int main() {

    shared_ptr<A> p1 = make_shared<A>(3);
    shared_ptr<A> p2 = p1;
    shared_ptr<A> p3 = p2;
    shared_ptr<A> p4 = p3;

    p1 = p4; // 1) 1st cyclic ref.
    cout<<p1.use_count()<<'\n';

    p1 = changeI(p4); // 2) 2nd cyclic ref.

    cout<<p1.use_count()<<'\n';

//  putchar('\n');
    cout<<endl;
}
Run Code Online (Sandbox Code Playgroud)

哪个输出

4
5
4

~A : 4
Run Code Online (Sandbox Code Playgroud)

是不是我误解了所提到的循环引用boost::shared_ptr?因为,我预计间接引用的不同输出思维p1意见后1)2).所以这段代码不需要boost::weak_ptr!那么什么是weak_ptr需要s 的循环引用?

提前致谢.

ltj*_*jax 22

是的,你误解了这个.在您的示例中,所有指针都指向同一个对象,而不是形成任何循环.

将p4赋值给p2是一个无操作,因为那些指针已经等于开头了.

这是一个带有实际循环引用的示例,可能会清除:

struct A
{
  std::shared_ptr<A> ptr;
};

void main()
{
  std::shared_ptr<A> x=std::make_shared<A>();
  std::shared_ptr<A> y=std::make_shared<A>();

  x->ptr = y; // not quite a cycle yet
  y->ptr = x; // now we got a cycle x keeps y alive and y keeps x alive
}
Run Code Online (Sandbox Code Playgroud)

你甚至可以使这更简单:

void main()
{
  std::shared_ptr<A> x=std::make_shared<A>();

  x->ptr = x; // never die! x keeps itself alive
}
Run Code Online (Sandbox Code Playgroud)

在这两个示例中,即使在离开main之后,shared_ptrs中的对象也永远不会被破坏.

  • 是的,严格来说这是操作系统的工作。我知道的所有操作系统都这样做。某些嵌入式操作系统可能不会。 (2认同)
  • 不,这几乎是一个循环的定义; 直接或间接指向自身的对象,因此永远不会丢失该引用. (2认同)