увеличить shared_ptr и «это» - PullRequest
5 голосов
/ 12 июля 2010

У меня есть два класса с отношениями родитель-ребенок (клиент, каталог, файл и т. Д.)

У меня есть

typedef boost::shared_ptr<Parent> ParentPtr

и в родительском классе метод, чтобы сделать ребенка

Мне нужны дочерние экземпляры, чтобы указатели были на их родителей.

class Child
{
 ....
     ParentPtr m_parent;
 ....
}

Я хочу, чтобы это был shared_ptr, чтобы родительский элемент не исчезал, пока есть существующие дочерние элементы. У меня также есть другие люди, которые держат ParentPtrs для родителя (фабричный метод для Parents возвращает ParentPtr)

Вопрос: как дать ребенку ParentPtr

попытка (1). In Parent :: ChildFactory

child->m_parent.reset(this);

это приводит к очень плохим вещам. Теперь есть 2 цепочки ParentPtr, указывающие на родителя; результатом является преждевременная смерть родителя

попытка (2). Родитель имеет

ParentPtr m_me;

, который копируется из возвращаемого значения родительской фабрики. Так что я могу сделать

child->m_parent = m_me;

Но теперь Родитель никогда не умирает, потому что содержит ссылку на себя

Ответы [ 2 ]

8 голосов
/ 12 июля 2010

Я вполне уверен, что enable_shared_from_this решит вашу проблему: http://live.boost.org/doc/libs/1_43_0/libs/smart_ptr/enable_shared_from_this.html

Если вы получили свой класс по специализации boost::enable_shared_from_this, тогда вы можете использовать shared_from_this() в функции-члене для полученияобщий указатель, которому принадлежит this (при условии, что он есть).

Например,

class Parent : public boost::enable_shared_from_this<Parent>
{
    void MakeParentOf(Child& c)
    {
        c.m_parent = shared_from_this();
    }
};
0 голосов
/ 12 июля 2010

Поскольку в другом ответе есть указатель, сначала вам нужно будет использовать enable_shared_from_this, чтобы получить shared_ptr, но затем дочерний элемент не может удерживать эту ссылку, это должен использовать weak_ptr. weak_ptr похож на shared_ptr, за исключением того, что он не будет содержать ссылку, пока вы не вызовете метод get(), который вернет вам обычный shared_ptr, от которого вы должны избавиться, как только сможете внутри ребенок.

...