2014-11-23 34 views
9

Döngüsel referansları kırmak için zayıf_pointerların kullanılabildiğini okudum.Nasıl zayıf_ptr kullanarak shared_ptr döngüsel referansı kırılır?

döngüsel referans Şimdi yukarıdaki

struct A 
{ 
boost::shared_ptr<A> shrd_ptr; 
}; 


boost::shared_ptr<A> ptr_A(boost::make_shared<A>()); 
boost::shared_ptr<A> ptr_b(boost::make_shared<A>()); 
ptr_A->shrd_ptr = ptr_b; 
ptr_b->shrd_ptr = ptr_A; 

döngüsel bir referans durumdur örneğini düşünelim ve ben weak_ptr kullanarak yukarıdaki döngüsel başvuru kırabilir nasıl bilmek istedi?

Güncelleme:

struct A 
{ 
    boost::weak_ptr<A> wk_ptr; 
}; 

    boost::shared_ptr<A> ptr_A (boost::make_shared<A>()); 
    boost::shared_ptr<A> ptr_B (boost::make_shared<A>()); 
    ptr_A->wk_ptr = ptr_B; 
    ptr_B->wk_ptr = ptr_A; 

Bu doğru bir yaklaşım olacaktır: öneri dayanarak aşağıdaki ile geldi alınan? Her iki referanslar A olduğunu söylüyor o zaman shared_ptr ise

#include <memory> 
#include <iostream> 

struct B; 
struct A { 
    std::shared_ptr<B> b; 
    ~A() { std::cout << "~A()\n"; } 
}; 

struct B { 
    std::shared_ptr<A> a; 
    ~B() { std::cout << "~B()\n"; } 
}; 

void useAnB() { 
    auto a = std::make_shared<A>(); 
    auto b = std::make_shared<B>(); 
    a->b = b; 
    b->a = a; 
} 

int main() { 
    useAnB(); 
    std::cout << "Finished using A and B\n"; 
} 

: Eğer AA bir referansı vardır B bir referansı vardır iki sınıfları A ve B sahip olduğu

+1

'A :: shrd_ptr' işlevini' boost :: weak_ptr' olarak değiştirin ve 'shared_ptr' başka bir yerde tutun. –

cevap

23

halkalı referansların klasik bir örneğidir B ve B'un mülkiyeti, alarm zillerini çalması gereken A'un sahipliğine sahiptir. Başka bir deyişle, A, B'u canlı tutar ve B, A'u canlı tutar.

Bu örnekte

örneklerini a ve b sadece bu yüzden biz yıkıcılar denilen değildir programı çalıştırdığınızda Gördüğümüz olarak işlev ancak bittiğinde onları yok edilmek istiyoruz useAnB() fonksiyonunda kullanılır.

Çözüm kimin kim olduğuna karar vermektir. Eğer programı çalıştırırsanız biz beklediğiniz gibi a ve b tahrip görüyoruz Sonra

struct B { 
    std::weak_ptr<A> a; 
    ~B() { std::cout << "~B()\n"; } 
}; 

: A o zaman weak_ptr şöyle ile B yılında A başvurusunu değiştirin B sahibi ama AB sahip değildir Diyelim .

Live demo

Düzenleme: Sizin durumunuzda, önerilen yaklaşım tamamen geçerli görünüyor. Sahipliği A'dan kaldırın ve başka bir şey A s.

+0

Çok iyi bir cevap - sadece bir +1 –

+0

verebilirim, daha sonra a.lock() öğesinden shared_ptr oluşturduğumuzda sorun (döngüsel referans) kalır mı? –

+1

@Explorer_N Sağlama 'B',' a.lock() 'dan oluşturulmuş bir' shared_ptr' için kalıcı olarak kalmaz. [Burada canlı demo'nun genişletilmiş bir sürümü] (http://melpon.org/wandbox/permlink/mdIkQ3QbFhaskdro) 'a.lock()' kullanma örneğini içerir. –