2012-06-18 8 views
5

Przypuśćmy, że muszę wykonać następujące czynności (To jest tylko pomysłowy kod do dyskusji na temat standardu C++, dlatego nie będę dyskutował, dlaczego zaprojektowałem go w ten sposób, więc nie zawracaj mi głowy czymś takim: twój projekt jest błędne.)Ten sam adres, wiele liczników shared_ptr, czy jest to zabronione standardem C++?

T* ptr = new T; 
shared_ptr<T> p(ptr); 
shared_ptr<T> q(ptr, SomeDeleterThatDoesnotDeleteButDoSomeOtherStuff()); 

Załóżmy logika gwarantuje p lub niektóre z jego kopii żyje dłużej niż wszystkie kopie q, więc praktycznie nie będzie żadnego problemu. Moje pytanie brzmi: czy jest zabronione przez standard C++, np. jednoznacznie określone jako UB według standardu C++, dla różnych współdzielonych liczników współdzielonych, aby współdzielić ten sam adres?

Dzięki.

+1

Co jeśli zwrócisz q; '? –

+0

@Peter Myślę, że to jest idea - wywołać non-deleter i zrobić coś użytecznego ze świadomością, że jakiś podzbiór odniesień jest teraz pusty. – Potatoswatter

+0

Projekt nie jest * taki * straszny ze względu na swój cel. Możesz zagwarantować odpowiednie zniszczenie, zamieniając niestandardowy deleter na taki, który * usuwa * usuwając, a także posiada swój własny 'shared_ptr' 1. na fikcyjny obiekt, który wykonuje akcję w swoim destruktorze lub 2. mając inny niestandardowy deletor, który wykonuje akcję . Ale te metody mogą być mniej wydajne, jeśli zbiór obiektów q zmienia się szybko w stosunku do zbioru odpowiednich właścicieli 'p'. – Potatoswatter

Odpowiedz

2

Nie mogę znaleźć niczego w standardzie (dobrze, końcowy projekt), który wyraźnie go wyklucza. Najbliższy mogę znaleźć to notatka w 20.9.11.2.10 shared_ptr casts

5 [Uwaga: pozornie równoważne wyrażenie shared_ptr (static_cast (r.get())) będzie ostatecznie doprowadzić niezdefiniowanej zachowań, próbując usunąć ten sam przedmiot dwa razy. -end note]

, która wydaje się zapominać o swojej sprawie z niestandardowym deleterem.

5

Jeśli pierwszy obiekt shared_ptr zostanie zniszczony, otrzymasz UB, ponieważ obiekty korzystające z drugiego mogą uzyskać dostęp do zwolnionego obiektu.

Ponieważ upewniłeś się, że pierwszy obiekt shared_ptr żyje dłużej niż drugi, nie uzyskasz UB.