diff --git a/include/mixins/BaseLinkMixin.h b/include/mixins/BaseLinkMixin.h index 5501a71..bbe6965 100644 --- a/include/mixins/BaseLinkMixin.h +++ b/include/mixins/BaseLinkMixin.h @@ -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); } diff --git a/src/main.cpp b/src/main.cpp index 4e9ec49..2feb4e3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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(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 } }