2014-07-17 10 views
5

Czy jest zagwarantowane, że weak_ptr wygaśnie, gdy shared_ptr zostanie zresetowany na ten sam adres, który zawiera?Czy jest zagwarantowane, że weak_ptr wygaśnie, gdy shared_ptr zostanie zresetowany na ten sam adres, który zawiera?

#include <cassert> 
#include <memory> 

int main() 
{ 
    int* i = new int(0); 
    std::shared_ptr<int> si(i); 
    std::weak_ptr<int> wi = si; 

    si.reset(i); 

    assert(wi.expired()); // wi.expired() == true (GCC 4.7) 
} 

Czy jest tak w przypadku, gdy wartość wi.expired() nie została zdefiniowana?

EDIT:

teraz modyfikować zapytania trochę:

To jest zagwarantowane, że weak_ptr wygasa gdy shared_ptr powraca do tego samego adresu, który zawierał shared_ptr kiedy to został zainicjowany weak_ptr?

#include <cassert> 
#include <memory> 

int main() 
{ 
    int* i = new int(0); 
    std::shared_ptr<int> si(i); 
    std::weak_ptr<int> wi = si; 

    si.reset(); 

    int* j = new int(0); 
    // Suppose that new returns the same address that contains variable i : 
    assert(j == i); 

    si.reset(j); 

    assert(wi.expired()); // wi.expired() == true (GCC 4.7) 
} 
+1

Powiązane pytanie: [Co stanie się po zresetowaniu std :: shared_ptr do siebie] (http: // stackoverflow.com/questions/9785656/what-happens-if-i-reset-a-stdshared-ptr-to-itself). – ComicSansMS

Odpowiedz

11

Po jednej stronie powinien. Po drugiej stronie nie jest właściwe przypisywanie tego samego wskaźnika do dwóch różnych wskaźników współużytkowanych (si-before-reset i si-after-reset). W rzeczywistości, powołując si.reset(i) zdarza się, że:

  • sędzia-count z si spada do 0
  • delete i jest wywoływana
  • odrodzonej si punkty i ponownie.

więc nowo przypisany i po resecie będzie wskazywać nie przydzielona pamięć i wi jest poprawnie upłynął (i dadzą początek do wysypać podczas si nie ma, w końcu, starając się ponownie usuwać i).

Dobrą praktyką jest nigdy nie odwoływać się do gołego wskaźnika po przypisaniu go do shared_ptr.

ODPOWIEDŹ PO EDIT:

To samo dotyczy też tam: fakt, że wskaźnik jest taki sam, nie ma nic wspólnego z shared_ptr i jego wewnętrznego Ref-count. Być może jest to wyraźniejsze dzięki przykładowi "zła". To jest złe:

int *i = new int; 

    std::shared_ptr<int> si1(i); 
    std::shared_ptr<int> si2(i); // deleting twice i on destruction of si2 - boom! 
    std::weak_ptr<int> wi1 = si1; 

    si1.reset(); 
    assert (wi1.expired());  // true 

ten jest podobny (naprawdę to samo) z pierwszego przykładu: SI1 i SI2 są dwa odrębne shared_ptr użytkownika (byli Si-przed-reset i Si-after-reset). Fakt, że si1 i si2 (błędnie) wskazuje na tę samą pamięć, nie ma nic wspólnego z życiem shared_ptr i połączonych słabych stron.

Bezwzględna wartość wskaźnika i nie jest używana do określenia liczby ref. Zarówno dla shared_ptr's, jak i dla weak_ptr. Tak, jest to gwarantowane!

W rzeczywistości, kiedy trzeba się shared_ptr obiektu od wewnątrz swojej klasie, trzeba enable_shared_from_this - Jeśli uzywasz shared_ptr(this) zamiast shared_from_this() pan coraz różnych shared_ptr za każdym razem - niszcząc przedmiot jak tylko pierwszy z nich straciłem rachubę z ref.

Powiązane problemy