2010-05-25 11 views
7

boost::intrusive_ptr wymaga zdefiniowania intrusive_ptr_add_ref i intrusive_ptr_release. Dlaczego nie jest podana klasa podstawowa, która to zrobi? Oto przykład: http://lists.boost.org/Archives/boost/2004/06/66957.php, ale na plakacie jest napisane: "Niekoniecznie uważam, że to dobry pomysł". Dlaczego nie?intrusive_ptr: Dlaczego nie jest udostępniana wspólna klasa podstawowa?

Aktualizacja: Nie sądzę, aby fakt, że ta klasa mogła zostać niewłaściwie wykorzystana z wieloma dziedziczeniami, jest wystarczającym powodem. Każda klasa wywodząca się z wielu klas bazowych z własną liczbą odwołań będzie miała ten sam problem. To, czy te wartości reflokowe są realizowane za pośrednictwem klasy bazowej, czy nie, nie ma znaczenia.

Nie sądzę, że jest jakiś problem z wielowątkowością; boost::shared_ptr oferuje liczenie odniesień atomowych i ta klasa może również.

+3

Na powiązana uwaga 'OSG :: ref_ptr' z biblioteki OpenSceneGraph używa najwyższego poziomu klasy bazowej (wspólny 'osg :: Referenced') za inwazyjną implementację inteligentnego wskaźnika. –

+3

Osg :: Referenced jest kompatybilny z boost :: intrusive_ptr, ponieważ zapewnia funkcje intrusive_ptr_add_ref() i intrusive_ptr_release(). Działa świetnie. –

Odpowiedz

2

Funkcja Boost zapewnia taką możliwość. Może być skonfigurowany zarówno dla wątku bezpieczny lub niebezpieczny refcounting wątku:

#include <boost/intrusive_ptr.hpp> 
#include <boost/smart_ptr/intrusive_ref_counter.hpp> 

class CMyClass 
    : public boost::intrusive_ref_counter< 
           CMyClass, 
           boost::thread_unsafe_counter> 
    ... 

boost::intrusive_ptr<CMyClass> myPtr; 

http://www.boost.org/doc/libs/1_62_0/libs/smart_ptr/intrusive_ref_counter.html

+0

Innymi słowy, odpowiedź na moje pytanie brzmi: "powinno być, a teraz jest" :) – Jon

+0

Wygląda na to, że był tam przez jakiś czas, ale trochę się poruszył. Oto najwcześniejszy odnośnik do dokumentu, który znalazłem: http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/utilities.html#header.boost.log.utility.intrusive_ref_counter_hpp –

3

Problem polegałby na wielokrotnym dziedziczeniu. Jeśli dziedziczysz od 2 obiektów implementujących tę bazę, to masz 2 liczniki do pojedynczego obiektu ... i to może spowodować spustoszenie.

W ten sposób należy wprowadzić metody wirtualne, aby klasa pochodna mogła zaimplementować zastąpienie, aby poprawnie zsynchronizować wiele liczników naraz ... Pewne kary za wydajność tutaj, zwłaszcza że w większości przypadków być całkowicie niepotrzebnym (nie byłoby żadnego przesłonięcia), ponieważ w końcu jest to użyteczne tylko w przypadku wielokrotnego dziedziczenia.

Oczywiście w środowiskach z wieloma wątkami można było (przez krótki czas) zsynchronizować liczniki (pierwszy został zwiększony, ale wątek został przerwany przed drugim) Nie mogę jeszcze myśleć o jakimkolwiek problemie przyczyną, ale nie jest to rozsądna sytuacja.

Dodajecie również bałagan do klasy, niektórzy klienci mogą nie potrzebować liczenia odwołań po wszystkim (jeśli tworzą obiekt na stosie).

myślę, że to nie jest dobry pomysł;)

+2

Dziedziczenie wielokrotne: ten problem występuje również, gdy masz dwie klasy bazowe, które implementują własną liczbę odwołań. To, czy ten refcount jest realizowany za pośrednictwem klasy bazowej, czy nie ma znaczenia. Wielowątkowe: shared_ptr ma atomowy inkrement/dekrement, więc ta klasa może również. "niektórzy klienci mogą nie potrzebować licznika odwołań": to jest powód, dla którego nie użyłbyś metody intrusive_ptr, a nie dlaczego nie ma klasy bazowej. – Jon

+1

@Jon: Zgadzam się na wielokrotne dziedziczenie, w rzeczywistości można wdrożyć intrusive liczenie odwołań bez klasy bazowej. Jednak nie zgadzam się z 2 innymi uwagami: dla MT 'shared_ptr' zapewnia łatwy dostęp do semantycznych atomów, ponieważ ma tylko jeden licznik, jeśli masz kilka liczników do utrzymania w stanie spójnym, potrzebujesz jawnego blokowania (nie ma więcej dostępnych opcji atomowych) i to oznacza, że ​​nad głową ... podążaj za białym królikiem ... –

+1

Dla części 'intrusive_ptr': jestem tutaj niepełny, ale zawsze uważałem, że podejście inwazyjne było" niewłaściwe "w tym sensie, że łączyło ono zarówno" funkcjonalną "klasę, jak i" zarządzanie ". Tak więc jest to krytyka za inwazyjny mechanizm liczenia odwołań. Uważam, że podejście "shared_ptr" jest bardziej solidne, a fakt, że nie można przypadkowo mieć dwóch liczników dla pojedynczego zestawu 'shared_ptr' jest miłym dodatkiem. –

4

Jest więc można użyć intrusive_ptr z klas, które już realizują dodawać i uwolnienie.

+0

Istnieją inne powody, dla których warto użyć intrusive_ptr (ślad pamięci, wydajność, konstrukcja z arbitralnej surowej wskazówki). – Jon

+0

To najlepszy powód, chociaż IMHO –