Bonjour tout le monde,
Je suis en train de construire un petit arbre basé sur les pointeurs intelligents.
J'ai mon objet (Node) contenant un std::weak_ptr pour son parent et une liste de std::weak_ptr pour ses enfants.
Ces différents objets sont stocker dans un conteneur me permettant d'accéder plus facilement aux différents noeuds.
Je souhaite :
- lorsque je supprime le parent de supprimer tous les enfants
- lorsque je supprime un enfant, il soit supprimer de son parent
Pour résoudre le 1), j'envoie un évènement pour dire à mon conteneur de supprimer le noeud.
Pour résoudre le 2), je demande au parent de parcourir toute la liste des enfants et de supprimer les enfants déjà supprimés.
Je voulais savoir si quelqu'un à une autre approche à me proposer (dont éviter de parcourir toute la liste des enfants pour supprimer ceux déjà supprimés).
Merci.
Voici un exemple d'implémentation de mon idée (sans la partie conteneur d'objet ni envoie d'évènement pour supprimer les enfants lors de la suppression du parent):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 #include <memory> #include <list> #include <iostream> using namespace std; class Node; typedef std::shared_ptr<Node> NodePtr; typedef std::weak_ptr<Node> NodeWPtr; class Node : public std::enable_shared_from_this<Node> { friend class NodeFactory; Node() = default; public: virtual ~Node() { if (NodePtr p = p_parent.lock()) { p->removeDeletedChild(); } for (NodeWPtr c : p_children) { if (NodePtr child = c.lock()) { // TODO: ajouter l'évènement pour demander au conteneur de supprimer child child->p_parent.reset(); } } } void addChild(NodePtr child) { if (child) { child->p_parent = getPtr(); // child est converti automatiquement en weak_ptr; p_children.push_back(child); } } const std::list<NodeWPtr> & getChildren() const { return p_children; } void removeDeletedChild() { std::list<NodeWPtr>::iterator it; for (it = p_children.begin(); it != p_children.end();) { NodePtr child = it->lock(); if (!child) { it = p_children.erase(it); } else { ++it; } } } NodePtr getPtr() { return shared_from_this(); } protected: NodeWPtr p_parent; std::list<NodeWPtr> p_children; }; class NodeFactory { public: NodePtr create() { return std::shared_ptr<Node>(new Node()); } }; int main() { NodeFactory factory; NodePtr parent = factory.create(); NodePtr child1 = factory.create(); NodePtr child2 = factory.create(); parent->addChild(child1); parent->addChild(child2); if (parent->getChildren().size() != 2) { std::cerr << "Problem to add children" << std::endl; return 1; } else { NodeWPtr tmpWChild1 = parent->getChildren().front(); NodeWPtr tmpWChild2 = parent->getChildren().back(); if (NodePtr tmpChild1 = tmpWChild1.lock()) { if (tmpChild1 != child1) { std::cerr << "tmpChild1 is different from child1" << std::endl; return 1; } } else { std::cerr << "The child1 is not added correctly" << std::endl; return 1; } if (NodePtr tmpChild2 = tmpWChild2.lock()) { if (tmpChild2 != child2) { std::cerr << "tmpChild2 is different from child1" << std::endl; return 1; } } else { std::cerr << "The child2 is not added correctly" << std::endl; return 1; } child2.reset(); if (parent->getChildren().size() != 1) { std::cerr << "Problem to remove children" << std::endl; return 1; } else { tmpWChild1 = parent->getChildren().front(); if (NodePtr tmpChild1 = tmpWChild1.lock()) { if (tmpChild1 != child1) { std::cerr << "tmpChild1 is different from child1" << std::endl; return 1; } } else { std::cerr << "The child1 is not added correctly" << std::endl; return 1; } } } std::cout << "All work correctly" << std::endl; return 0; }
Partager