2012-03-29 15 views
5

Używam libev, który wymaga przesyłania moich danych do pustki *, aby zachować ich predefiniowane struktury. Muszę rzucić boost :: shared_ptr do void *, a następnie odrzucić void * z powrotem do boost :: shared_ptr. Oto mój kod to zrobićZwiększenie rzutowania shared_ptr do void *

void foo(boost::shared_ptr<string>& a_string) 
{ 
void* data = (void*)a_string.get(); 
boost::shared_ptr<string> myString((string*)data); 
} 

Jestem całkiem pewien, że to działa dobrze, jednak sposób, w jaki mój kod jest ustawiony wierzę wszystkie odniesienia shared_ptr do mojego ciąg będą poza zakresem tej metody odlewania jak nie zwiększy use_count, a tym samym shared_ptr, zwalnia pamięć, gdy wciąż jej potrzebuję.

Czy istnieje sposób na ręczne zwiększenie/zmniejszenie wartości użytkowej? Idealnie zwiększyłbym use_count, gdy rzucę do pustki *, przekazuję moją pustkę * do innej funkcji, odrzuć pustkę * z powrotem do shared_ptr i zmniejsz wartość use_count.

Jeśli ktoś zna inne rozwiązanie tego problemu, mógłbym skorzystać z pomocy.

+1

Można przechowywać watcher w klasie, która zawiera zarówno watcher i 'shared_ptr'. Zapewni to, że czas życia obserwatora zostanie dopasowany lub przekroczony przez czas życia obiektu posiadanego przez 'shared_ptr'. Dlaczego nie przechowywać adresu samego 'shared_ptr' zamiast zapisywać adres wskazanego obiektu? – Mankarse

+0

Znalazłem hack around przez tworzenie struct, który zawiera shared_ptr i rzutowanie struct do void *. Nie jestem pewien, co sądzę o tym rozwiązaniu.Ponadto na forum zobaczyłem, że nie powinieneś używać adresu shared_ptr. –

+0

@ user1229962: Co przekazujesz 'void *' do? –

Odpowiedz

4

Jedynym sposobem na to, aby przydzielić shared_ptr miejsce, które będzie żyć wystarczająco długo, a następnie ustawić void*, aby wskazać na to.

0

spróbować weak_ptr:

shared_ptr<int> p(new int(5)); 
weak_ptr<int> q(p); 

Edit: Niestety nie przeczytałem pytanie prawidłowo; można starać się utrzymać go w zakresie, więc nie ma się umyć

Aktualizacja: Słaby wskaźnik może rzeczywiście działać, jeśli odwołać się do zmiennej po wywołaniu bo wtedy kompilator cant optymalizacji zniszczenie a_string shared_ptr (stąd zapobiec Decr RefCount do zera -> release) przed dokonaniem wykorzystanie bazowego wskaźnika

więc można to zrobić:

void foo(boost::shared_ptr<string>& a_string) 
{ 
void* data = (void*)a_string.get(); 
boost::shared_ptr<string> myString((string*)data); 
weak_ptr<string> temp(a_string); // prevent destruction before above line 
// or reference a_string in any meaningless way that CANT be optimised out 
// pre-emptively by the compiler 
} 

a_string może jeszcze trzeba odwoływać gdzieś poza foo d epending od kontekstu i co robisz ze wskaźnikiem void (i jeśli to tworzy nową kopię lub działa na pustych danych)

+1

Funkcja weak_ptr nie zwiększa wartości use_count, dzięki czemu pamięć zostanie zwolniona. W jaki sposób pomoc dla weak_ptr? –

+1

zaktualizowałem moją odpowiedź. –

1

Jeśli rzucisz void* powrotem do boost::shared_ptr, będzie to nowa wspólna wskaźnik, nie są połączone z żadnymi innymi współdzielonymi wskaźnikami, które wskazują również na pamięć wskazywaną przez zmienną `void*.

Co należy zrobić, to dodać obsługę klas enabled_shared_from_this do klas, o których myślisz, używając shared_ptrs z tym kodem.

Pozwala to uzyskać shared_ptr, która będzie współdzielić własność z istniejącymi shared_ptrs za pośrednictwem funkcji składowej (shared_from_this) na twojej klasie.

Zobacz boost enabled_shared_from_this docs więcej szczegółów.