в следующем случае произошла утечка памяти, я сомневаюсь в этом. в тесте () весело:
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class parent;
class children;
typedef boost::shared_ptr<parent> parent_ptr;
typedef boost::shared_ptr<children> children_ptr;
class parent
{
public:
~parent() { std::cout <<"destroying parent\n"; }
public:
children_ptr children;
};
class children
{
public:
~children() { std::cout <<"destroying children\n"; }
public:
parent_ptr parent;
};
void test()
{
parent_ptr father(new parent());
children_ptr son(new children);
father->children = son;// parent_ptr_count=1, children_ptr_count=2
son->parent = father;// parent_ptr_count=2, children_ptr_count=2
//1,2,3 See the note below
}
void main()
{
std::cout<<"begin test...\n";
test();
std::cout<<"end test.\n";
}
// childern_ptr выскакивает из стека, я думаю, что childern_ptr_count— и parent_ptr_count—
// parent_ptr извлекается из стека, я думаю, childern_ptr_count— и parent_ptr_count—
// но на самом деле это не так, почему?
Я надеюсь, что кто-то может мне помочь, большое спасибо.
Я считаю, что это именно тот сценарий в этом примере: https://visualstudiomagazine.com/articles/2012/10/19/circular-references.aspx
Это циклическая ссылка, и решение состоит в том, чтобы один из указателей был слабым указателем. Хотя статья предназначена для реализации общих и слабых указателей в C ++ 11, у boost также есть слабый указатель по той же причине.
когда son
уничтожен, счетчик ссылок для children
объект падает, но счетчик ссылок для parent
объект не, потому что children
объект, который содержит parent_ptr
не был уничтожен (потому что его счетчик ссылок равен 1, а не 0).
Аналогично, когда father
уничтожен, счетчик ссылок для parent
объект падает, но счетчик ссылок для children
объект не, потому что parent
объект, который содержит children_ptr
не был уничтожен (потому что его счетчик ссылок равен 1, а не 0).
Как и в других ответах, вы создали круговая ссылка.
Вот решение. Когда у вас есть указатели, указывающие друг на друга, часто бывает полезно использовать weak_ptr
, Это делает указатель, который вы можете превратить в shared_ptr
и когда это не shared_ptr
он не увеличивает счетчик ссылок, поэтому позволяет уничтожать объекты.
Вот пример:
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class parent;
class children;
typedef boost::shared_ptr<parent> parent_ptr;
typedef boost::shared_ptr<children> children_ptr;
typedef boost::weak_ptr<parent> parent_weak_ptr;
typedef boost::weak_ptr<children> children_weak_ptr;
class parent
{
public:
~parent() { std::cout <<"destroying parent\n"; }
public:
children_weak_ptr children;
};
class children
{
public:
~children() { std::cout <<"destroying children\n"; }
public:
parent_weak_ptr parent;
};
void test()
{
parent_ptr father(new parent());
children_ptr son(new children);
father->children = son;// parent_ptr_count=1, children_ptr_count=1
son->parent = father;// parent_ptr_count=1, children_ptr_count=1
}
void main()
{
std::cout<<"begin test...\n";
test();
std::cout<<"end test.\n";
}
С помощью этого кода дочерние и родительские элементы уничтожаются, и они могут обращаться друг к другу, используя lock()
функция на weak_ptr
превратить это в shared_ptr
, Вот несколько документов:
boost::weak_ptr
документы
std::weak_ptr
документы