2010-12-13 14 views
10

Po prostu bawię się inteligentnymi wskaźnikami w nadchodzącym nowym standardzie C++. Jednak nie rozumiem użycia funkcji shared_from_this. Oto co mam:enable_shared_from_this (C++ 0x): co robię źle?

#include <iostream> 
#include <memory> 

class CVerboseBornAndDie2 : public std::enable_shared_from_this<CVerboseBornAndDie2> 
{ 
public: 
    std::string m_Name; 
    CVerboseBornAndDie2(std::string name) : m_Name(name) 
    { 
     std::cout << m_Name << " (" << this << ") is born!" << std::endl; 
    } 
    virtual ~CVerboseBornAndDie2() 
    { 
     std::cout << m_Name << " (" << this << ") is dying!" << std::endl; 
    } 
}; 

int main(){ 
    CVerboseBornAndDie2* vbad = new CVerboseBornAndDie2("foo"); 
    std::shared_ptr<CVerboseBornAndDie2> p = vbad->shared_from_this(); 
} 

i rzuca wyjątek std :: bad_weak_ptr w linii

std::shared_ptr<CVerboseBornAndDie2> p = vbad->shared_from_this(); 

gdybym zamiast robić

std::shared_ptr<CVerboseBornAndDie2> p(vbad); 

to działa i mogę potem zrobić

std::shared_ptr<CVerboseBornAndDie2> p2 = p.get()->shared_from_this(); 

tak musi być obiekt należeć do jednego shared_ptr, zanim będę mógł używać shared_from_this? Ale skąd mogę to wiedzieć wcześniej?

Odpowiedz

22

Jest warunkiem koniecznym użycia shared_from_this, który musi istnieć przynajmniej jeden shared_ptr, który jest właścicielem danego obiektu. Oznacza to, że możesz użyć tylko shared_from_this, aby pobrać shared_ptr, który jest właścicielem obiektu, do którego masz odniesienie lub wskaźnik, którego nie możesz użyć do sprawdzenia, czy taki obiekt jest własnością shared_ptr.

Musisz przerobić projekt, aby mieć pewność, że jakimkolwiek takim obiektem jest zarządzany przez shared_ptr lub że nigdy nie musisz wiedzieć lub w końcu (i co najmniej pożądane) możesz stworzyć inny sposób zarządzania ta wiedza.

+0

Nie można po prostu wstawić bloku try o wywołanie shared_from_this, jeśli chcesz dowiedzieć się, czy obiekt jest trzymany przez shared_ptr? Nie wiem jak jest określona w (nadchodzącym) standardzie, ale nie wydaje się niezdefiniowanym zachowaniem - rzuca wyjątek. – nobar

+1

@nobar: Byłoby to z grubsza niebezpieczne. Będziesz polegać na nieudokumentowanych szczegółach implementacji. 'shared_from_this' nie jest metodą sprawdzającą, czy obiekt jest własnością współużytkowanego wskaźnika; jest to metoda pobierania współdzielonego wskaźnika z obiektu, którego właścicielem jest współużytkowany wskaźnik. –

+0

Myślę, że masz rację. Wersja robocza C++ 0x mówi "Powinna istnieć co najmniej jedna instancja shared_ptr p, która jest właścicielem & t.", Ale nie mówi, co stanie się inaczej. Przedstawia implementację pod względem weak_ptr (co oznaczałoby, że wyjątek zostanie zgłoszony w przypadku błędu), ale to tylko "sugestia". Zastanawiam się, czy obsługa błędów ostatecznie zostanie lepiej określona. – nobar

15

Aby przedłużyć odpowiedź Charlesa, podczas korzystania z enable_shared_from_this zwykle potrzebujesz czegoś takiego jak poniżej, aby zagwarantować, że istnieje shared_ptr.

+1

'create()' powinno być 'statyczne', czyż nie? –

+0

@ Abyss.7: Rzeczywiście. – ronag

+1

Aby mieć domyślnie opcję udostępniania, możesz użyć czegoś podobnego do: 'try {return shared_from_this(); } catch (const bad_weak_ptr &) {return make_shared (); } ' –

Powiązane problemy