2013-10-02 13 views
8

Chciałbym zawinąć surowy wskaźnik do jakiegoś inteligentnego wskaźnika, aby zapobiec usunięciu wewnątrz klasy wywołującej. Właściciel obiektu pod wskaźnikiem znajduje się poza klasą. Wygląda na to, że nie pasuje boost::shared_ptr i std::auto_ptr. Poniżej znajduje się przykład obniżona:Tworzenie weak_ptr <> z surowego wskaźnika

class Foo { 
    boost::weak_ptr<Bar> m_bar; 
public: 
    void setBar(const Bar *bar) { // bar created on heap 
    m_bar = bar;    // naturally compilation error 
    } 
}; 

oczywiście, wywołuje błąd kompilacji. Jaki jest poprawny sposób inicjowania weak_ptr z nieprzetworzonego wskaźnika (jeśli istnieje)?

+0

możliwy duplikat [Shared \ _ptr & słabego \ _ptr konwersje] (http://stackoverflow.com/questions/17522020/shared-ptr-weak-ptr-conversions) –

+1

Jeśli chcesz zapobiec usunięciu tego wskaźnika w klasie, nie wywołuj na nim 'delete', a nie udostępniaj funkcji akcesora, które eksponują wskaźnik na klientach. 'weak_ptr' jest przeznaczone do widoku nie będącego właścicielem obiektu posiadanego przez' shared_ptr'. Gdybyś był w stanie jakoś wsadzić ten wskaźnik w 'weak_ptr', nie miałby pojęcia, czy wskaźnik wygasł, ani też nie uniemożliwi mi wywołania' delete m_bar.lock(). Get(); 'w twojej klasie. Nigdy nie da się uczynić wszystkiego w 100% bez idioty. – Praetorian

Odpowiedz

10

Nie można tego zrobić, można utworzyć tylko weak_ptr z shared_ptr lub innego weak_ptr. Tak więc pomysł polegałby na tym, że właściciel wskaźnika trzymał metodę shared_ptr zamiast surowego wskaźnika, a wszystko powinno być w porządku.

1

Przekaż udostępniony wskaźnik zamiast wskaźnika nieprzetworzonego i utwórz wskaźnik słabości z udostępnionego wskaźnika. Jest to jedyny sposób, jeśli właściciel wskaźnika znajduje się poza klasą.

4

Celem słabego wskaźnika jest uniemożliwienie użycia surowego wskaźnika, jeśli został usunięty. Jeśli jednak masz surowy wskaźnik, słaby wskaźnik nie ma możliwości dowiedzenia się, że został usunięty. Zamiast tego musisz mieć shared_ptr gdzieś, który "jest właścicielem" surowego wskaźnika. Następnie możesz utworzyć plik weak_ptr, który odwołuje się do shared_ptr.

Kiedy shared_ptr wychodzi poza zasięg i jest ostatnim "silnym" wskaźnikiem inteligentnym, automatycznie usuwa surowy wskaźnik. Następnie, gdy spróbujesz zablokować weak_ptr, zobaczysz, że nie ma "silnego" wskaźnika, a zatem obiekt nie istnieje.

2

Wszystko powiedziałeś wydaje całkowicie uzasadnione, z wyjątkiem jednej rzeczy:

void setBar(const Bar *bar) 

To nie powinno zająć surowy wskaźnik. Najlepszym rozwiązaniem powinno być uzyskanie weak_ptr, lub ewentualnie shared_ptr, jeśli masz jakiś przekonujący argument.

Faktyczny właściciel danego obiektu powinien skonstruować weak_ptr, a następnie zadzwonić pod numer setBar. Zachowuje to semantykę własności. Wygląda na to, że to, co robisz, polega na tym, że obiekt będący właścicielem bierze surowy wskaźnik i przekazuje go do setBar. Stwarza to luki semantycznej w własności obiektu.

5

Jedynym sposobem na to jest dotarcie do shared_ptr lub weak_ptr że posiada wskaźnik, w przeciwnym razie weak_ptr nie ma sposobu, aby znaleźć istniejący właściciela w celu dzielenia własności z nim.

Jedynym sposobem, aby dostać shared_ptr z surowego wskaźnik, który jest już w posiadaniu innego shared_ptr jest jeśli Bar wywodzi enable_shared_from_this<Bar>, to można zrobić

m_bar = bar->shared_from_this(); 
Powiązane problemy