2010-05-17 2 views

ответ

16

A weak_ptr содержит ссылку, не относящуюся к собственности, поэтому объект, к которому он относится, может не существовать больше. Было бы опасно использовать необработанный указатель, удерживаемый weak_ptr.

Правильный подход заключается в продвижении weak_ptr в shared_ptr с использованием weak_ptr::lock() и получения указателя.

Boost weak_ptr documentation объясняет, почему было бы небезопасно обеспечивать функциональность get() как часть weak_ptr, а также примеры кода, которые могут вызвать проблемы.

+0

В этом случае вы можете остаться с обвисшим указателем, если вы получите необработанный указатель на 'shared_ptr', который впоследствии будет уничтожен ... в случае Multithread вы даже можете остаться с висящим указателем в начале код 'if (! weak.expired()) weak-> run();' поскольку объект, на который указывает, может быть уничтожен между тестом и выполнением метода (я полагаю, что сам метод правильно синхронизирован) ... –

+3

@Matthieu: конечно вы * можете *, так же как вы можете остаться с обвисшим указателем, если вы явно «удаляете» объект, но держите указатель на него. Суть в том, что нужно продвигать 'weak_ptr' в' shared_ptr', заключается в том, что он рекомендует вам правильно использовать использование необработанного указателя, следуя правилам, которые обычно используются для 'shared_ptr :: get'. Не было бы эквивалентного способа правильно охватить использование необработанного указателя, полученного непосредственно из 'weak_ptr'. –

2

Сначала вы должны получить shared_ptr из weak_ptr перед тем, как овладеть необработанным указателем.

Вы можете позвонить lock получить shared_ptr, или shared_ptr конструктор:

boost::weak_ptr<int> example; 
... 

int* raw = boost::shared_ptr<int>(example).get(); 
+8

Как написано, это небезопасно - вы можете остаться с обвисшим указателем, если объект будет удален при уничтожении временного 'shared_ptr'. Вы должны держать 'shared_ptr' до тех пор, пока используете необработанный указатель. –

3

Это старый вопрос, и принятый ответ хороший, поэтому я не решаюсь опубликовать еще один ответ, но одна вещь, которая кажется отсутствует хороший идиоматических пример использования:

boost::weak_ptr<T> weak_example; 
... 
if (boost::shared_ptr<T> example = weak_example.lock()) 
{ 
    // do something with example; it's safe to use example.get() to get the 
    // raw pointer, *only if* it's only used within this scope, not cached. 
} 
else 
{ 
    // do something sensible (often nothing) if the object's already destroyed 
} 

ключевым преимуществом этой идиомы является то, что сильный указатель области видимости КРП-истинный блок, который помогает предотвратить случайное использование, не инициализирован ссылки, или хранение сильная ссылка на длинные чем это действительно необходимо.

Смежные вопросы