Шаблон классаweak_ptrхранит «слабую ссылку» на объект, который уже управляетсяshared_ptr. Для доступа к объектуweak_ptrможет быть преобразован вshared_ptrс использованиемshared_ptrконструктораили функции членазамка. Когда последнийshared_ptrк объекту уходит и объект удаляется, попытка получитьshared_ptrизweak_ptrэкземпляров, которые относятся к удаленному объекту, потерпит неудачу: конструктор бросит исключение типаboost::bad_weak_ptr, аweak_ptr::lockвернетпустойshared_ptr.
Каждыйweak_ptrсоответствуетCopyConstructibleиAssignableтребованиям стандартной библиотеки C++, и поэтому может использоваться в стандартных библиотечных контейнерах. Операторы сравнения поставляются таким образом, чтобыweak_ptrработал с ассоциативными контейнерами стандартной библиотеки.
слабые_ptrоперации никогда не бросают исключения.
Шаблон класса параметризован наТ, тип объекта, на который указывается.
По сравнению сshared_ptr,weak_ptrобеспечивает очень ограниченное подмножество операций, поскольку доступ к его сохраненному указателю часто опасен в многопоточных программах, а иногда небезопасен даже в пределах одного потока (то есть он может вызывать неопределенное поведение). Притворитесь на мгновение, чтоweak_ptrимеетфункцию, которая возвращает необработанный указатель, и рассмотрите этот невинный фрагмент кода:
shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);
// some time later
if(int * r = q.get())
{
// use *r
}
Представьте себе, что после, если, но непосредственно передrиспользуется другой поток выполняет утверждение<p.reset()>.r— висящий указатель.
Решение этой проблемы заключается в создании временногоshared_ptrизq:
shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);
// some time later
if(shared_ptr<int> r = q.lock())
{
// use *r
}
Теперьrсодержит ссылку на объект, на который указывалq. Даже если<p.reset()>выполнен в другой нити, объект будет оставаться в живых до тех пор, покаrне выйдет из области действия или не будет сброшен. Получивshared_ptrк объекту, мы фактически заблокировали его от разрушения.
Эффекты:Еслиrявляетсяпустым, конструируетпустымслабым_ptr; в противном случае конструируетслабым_ptr, которыйразделяет право собственностисr, как если бы хранил копию указателя, хранящегося вr.
template<class T, class U>
bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b);
Возврат:неопределенное значение, такое, что
operator< is a strict weak ordering as described in section 25.3 [lib.alg.sorting]
of the C++ standard;
under the equivalence relation defined by operator<, !(a
< b) && !(b < a), two weak_ptr instances
are equivalent if and only if they share ownership or are both empty.
Бросает:ничего.
Примечания:Позволяет использовать в качестве ключей в ассоциативных контейнерахweak_ptrобъекты.
Q.Может ли объект создать для себяслабый_ptrв своем конструкторе?
A.No. Aweak_ptrможет быть создан только изshared_ptr, и в момент строительства объекта еще не существуетshared_ptrдля объекта. Даже если бы вы могли создать временныйshared_ptrкэтому, он вышел бы из области действия в конце конструктора, и всеслабые_ptrэкземпляры мгновенно истекли бы.
Решение состоит в том, чтобы сделать конструктор частным и предоставить заводскую функцию, которая возвращаетshared_ptr:
class X
{
private:
X();
public:
static shared_ptr<X> create()
{
shared_ptr<X> px(new X);
// create weak pointers from px here
return px;
}
};
$Date$
Авторское право 1999 Грег Колвин и Беман Доуз. Авторское право 2002 Дарин Адлер. Авторское право 2002-2005 годы Питер Димов. Распространяется под лицензией Boost Software License, версия 1.0. См. сопроводительный файлLICENSE_1_0.txtили копию наhttp://www.boost.org/LICENSE_1_0.txt
Статья weak_ptr раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.