Я сейчас собираю приложение, которое в значительной степени опирается на shared_ptr
, и пока все выглядит хорошо - я сделал свою домашнюю работу и довольно неплохо представляю некоторые подводные камни использования shared_ptr
с.
Одна из наиболее известных проблем с shared_ptr
- это циклические зависимости - эти проблемы можно решить путем хранения weak_ptr
s, которые не влияют на время жизни объектов в цепочке. Тем не менее, я изо всех сил пытаюсь разобраться, когда необходимо сохранить указатель на внешний объект через weak_ptr
- Я не уверен, запрещен ли он, не рекомендуется или безопасен .
Следующая диаграмма описывает то, что я имею в виду (черные стрелки указывают shared_ptr
; пунктирные обозначают weak_ptr
):
альтернативный текст http://img694.imageshack.us/img694/6628/sharedweakptr.png
- Родитель содержит
shared_ptr
s для двух детей, оба из которых указывают на родителя с помощью weak_ptr
.
- В конструкторе первого потомка я получаю через родительский
weak_ptr
указатель на второго потомка и сохраняю его локально.
Код выглядит так:
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
class child;
class child2;
class parent;
class parent : public boost::enable_shared_from_this<parent>
{
public:
void createChildren()
{
_child2 = boost::make_shared<child2>(shared_from_this());
_child = boost::make_shared<child>(shared_from_this());
}
boost::shared_ptr<child> _child;
boost::shared_ptr<child2> _child2;
};
class child
{
public:
child(boost::weak_ptr<parent> p)
{
_parent = p;
_child2 = boost::shared_ptr<parent>(p)->_child2; // is this safe?
}
boost::weak_ptr<parent> _parent;
boost::shared_ptr<child2> _child2;
};
class child2
{
public:
child2(boost::weak_ptr<parent> p)
{
this->_parent = p;
}
boost::weak_ptr<parent> _parent;
};
int main()
{
boost::shared_ptr<parent> master(boost::make_shared<parent>());
master->createChildren();
}
Я проверил это, и оно кажется работает нормально (я не получаю никаких сообщений об утечках памяти), однако мой вопрос: Это безопасно? А если нет, то почему?