qosd: обезопашен обход дерева с модификацией

Примеров итератора с доступом на чтение я много оставил, а пример
модификации дерева только один. И тот я сразу забыл перевести на
итераторы (range-based for loop).

Т.к. проход теперь не по вектору (он давал экземпляр умного указателя),
а по обычному указателю (собственному прокси, если точнее), то узел
разрушался уже в процессе его отключения от дерева. Добавил удержание
ссылки в сам `unlinkParent()` (ну, нам действительно может быть нужно
только безвозвратное удаление поддерева) и пример в `main.cpp` расширил
и прокомментировал.
master
Сергей Маринкевич 4 months ago
parent 5b515eaf19
commit dedd7df19c

@ -37,7 +37,15 @@ public:
auto parentLink = parent->getLink();
parentLink->removeChild(getNode());
/* NOTE:
*
* Keep a reference to the node we gonna to unlink.
* Otherwise, we'll disappear between `removeChild` and
* `setParent`. Do not rearrange these calls, because
* we want to modify the tree top down.
*/
auto node = getNode();
parentLink->removeChild(node);
getLink()->setParent(nullptr);
}

@ -119,11 +119,32 @@ int main() {
logger.info("Unlinking ComplexChild1 and ComplexChild3...\n");
child1->unlinkParent();
for (auto child : root->getLink()->getChildren()) {
NodePtr childNode = std::dynamic_pointer_cast<INode>(child);
if (childNode->name() == "ComplexChild3") {
childNode->unlinkParent();
for (auto child : traversal::BFS(root)) {
if (child->name() == "ComplexChild3") {
/* Avoid of disconnecting a node of the tree
* we're traversing. Method holds reference
* to it's object itself. But iterator ignores
* smart pointers, feeling free to dereference
* the destroyed object.
*/
#if 1
/* Keep in mind to keep your reference until
* the cycle ends, if you want more than just
* remove subtree.
*/
NodePtr node = *child;
node->unlinkParent();
std::cout << "Unlinked: "
<< node->name() << std::endl;
break;
#else
/* Otherwise, just break immediately you
* unlinked a node. The current pointer is not
* a valid pointer anymore.
*/
child->unlinkParent();
break;
#endif
}
}

Loading…
Cancel
Save