2015-01-12 16 views
9

Mam metodę na klasy, aby uczynić konkretnym przypadku „aktywna” instancję:Obsada „to” std :: shared_ptr

void makeActive() { activeInstance = this; } 

Jednak to nie działa, ponieważ activeInstance ma typ std::shared_ptr<ClassName>. Jak mogę odrzucić this do ?

+0

możliwy duplikat [Utwórz doładowanie :: współdzielone \ _ptr do istniejącej zmiennej] (http://stackoverflow.com/questions/8466459/create-a-boostshared-ptr-to-an-isting-variable) – timrau

+2

Używa on 'std :: shared_ptr', więc niektóre semantyki mogą się różnić. –

Odpowiedz

22

Jeśli obiekt jest już własnością przez shared_ptr można produkować inny shared_ptr poprzez swój przedmiot dziedziczą std::enable_shared_from_this

Kod ten będzie następnie pracować:

void makeActive() { activeInstance = shared_from_this(); } 

Jeśli obiekt jest nie był już własnością przez shared_ptr, to na pewno nie chcesz go utworzyć w makeActive(), ponieważ shared_ptr spróbuje usunąć twój obiekt kiedy ostatni zostanie zniszczony.

+0

Możesz nadal utworzyć shared_ptr, jeśli twój obiekt nie jest już przez niego utrzymywany. Zobacz moją odpowiedź. –

+0

@JohnZwinck Całkowicie się zgadzam ... widać, że uważałem, aby nie powiedzieć, że * nie można tego zrobić *. –

+2

Powiedziałeś, że "shared_ptr spróbuje usunąć twój obiekt, gdy ostatni zostanie zniszczony", ale nie jest to prawdą, jeśli użyjesz null deletera, jak wyjaśnię w mojej odpowiedzi. Powiedzenie "jesteś pewien, że nie chcesz go tworzyć" jest zbyt stanowczym stwierdzeniem, ponieważ można to zrobić bezpiecznie. –

3

To będzie "działać" (ale patrz niżej):

activeInstance.reset(this); 

Problem polega na tym, co robi to znaczy? Gdy activeInstance wykracza poza zakres, this będzie delete d. To może nie być to, czego chcesz. Należy również przeczytać o enable_shared_from_this, który pozwoliłby Ci powiedzieć:

activeInstance = shared_from_this(); 

Inną opcją jest użycie „zerowej Deleter”, czyli określenie funkcji Deleter który nic nie robi:

void NoDelete(void*) {} 

activeInstance.reset(this, NoDelete); 

W wielu przypadkach będzie to bezpieczne i poprawne rozwiązanie, zakładając, że this zostanie usunięte przez inną metodę w innym miejscu, a nie przed ostatnim dereferencją activeInstance.

+0

Jestem prawie pewny, że 'activeInstance' jest globalnym lub statycznym członkiem klasy, a zatem nie wykracza poza zakres. –

+1

@MikeDeSimone: cóż, zostanie zniszczony przy wyjściu programu, co może nadal prowadzić do podwójnego usunięcia, a więc niezdefiniowanego zachowania. –

+4

Lub użyj konstruktora aliasów zamiast delullera pustego: 'activeInstance = std :: shared_ptr (std :: shared_ptr (), this);' –

Powiązane problemy