diff --git a/include/links/BaseLink.h b/include/links/BaseLink.h index a6797ab..d57b5ce 100644 --- a/include/links/BaseLink.h +++ b/include/links/BaseLink.h @@ -13,6 +13,10 @@ public: void removeChild(const LinkPtr& child) override { children_.erase(std::remove(children_.begin(), children_.end(), child), children_.end()); } + + ~BaseLink() override { + std::cout << "--- Destructor called for: " << "BaseLink" << "\n"; + } protected: std::vector children_; std::weak_ptr owner_node_; diff --git a/include/mixins/LazyLinkMixin.h b/include/mixins/LazyLinkMixin.h index 3a512c1..9d0e47a 100644 --- a/include/mixins/LazyLinkMixin.h +++ b/include/mixins/LazyLinkMixin.h @@ -1,4 +1,5 @@ #pragma once +#include #include "ifaces/INode.h" #include "links/LeafLink.h" #include "links/OneToManyLink.h" @@ -28,6 +29,10 @@ public: return link_; } + ~LazyLinkMixin() override { + std::cout << "--- Destructor called for: " << "LazyLinkMixin" << "\n"; + } + protected: virtual std::shared_ptr getShared() = 0; NodePtr getSelf() override { return getShared(); } diff --git a/include/nodes/SimpleNode.h b/include/nodes/SimpleNode.h index 50082e4..8e501df 100644 --- a/include/nodes/SimpleNode.h +++ b/include/nodes/SimpleNode.h @@ -1,5 +1,6 @@ #pragma once #include "mixins/LazyLinkMixin.h" +#include class SimpleNode : public LazyLinkMixin, public std::enable_shared_from_this { @@ -11,6 +12,9 @@ public: return std::make_shared(std::move(name)); } const std::string& name() const override { return name_; } + ~SimpleNode() { + std::cout << "--- Destructor called for: " << name_ << "\n"; + } protected: std::shared_ptr getShared() override { return shared_from_this(); diff --git a/src/main.cpp b/src/main.cpp index 4f225e3..cba1e65 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#include "nodes/SimpleNode.h" +#include "nodes/SimpleNode.h" // Путь изменен #include void printTree(const NodePtr& startNode, int indent = 0) { @@ -12,24 +12,40 @@ void printTree(const NodePtr& startNode, int indent = 0) { } int main() { - auto root = SimpleNode::create("Root"); - auto child1 = SimpleNode::create("Child1"); - auto child2 = SimpleNode::create("Child2"); + std::cout << "Entering main scope...\n\n"; - root->linkChild(child1); - root->linkChild(child2); + // Начало новой области видимости + { + auto root = SimpleNode::create("Root"); + auto child2 = SimpleNode::create("Child2"); - auto subchild = SimpleNode::create("SubChild"); - child1->linkChild(subchild); + root->linkChild(child2); - std::cout << "Initial tree:\n"; - printTree(root); + { + auto child1 = SimpleNode::create("Child1"); + root->linkChild(child1); + auto subchild = SimpleNode::create("SubChild"); + child1->linkChild(subchild); + auto child3 = SimpleNode::create("Child3"); + root->linkChild(child3); + auto subchild2 = SimpleNode::create("SubChild2"); + child3->linkChild(subchild2); - std::cout << "\nUnlinking Child1...\n"; - child1->unlinkParent(); + std::cout << "Initial tree:\n"; + printTree(root); - std::cout << "\nFinal tree:\n"; - printTree(root); + std::cout << "\nUnlinking Child1...\n"; + child1->unlinkParent(); + std::cout << "\nTree after unlink:\n"; + printTree(root); + } + + std::cout << "\nTree after scope out:\n"; + printTree(root); + + } // <--- КОНЕЦ ОБЛАСТИ ВИДИМОСТИ + + std::cout << "\nExited main scope. All smart pointers destroyed.\n"; return 0; } diff --git a/tree.cc b/tree.cc deleted file mode 100644 index 17ecd8c..0000000 --- a/tree.cc +++ /dev/null @@ -1,208 +0,0 @@ -#include -#include -#include -#include -#include -#include - -// Forward declarations -class INode; -class ILink; -class ILinkMixin; - -using NodePtr = std::shared_ptr; -using LinkPtr = std::shared_ptr; - -// --- ИНТЕРФЕЙСЫ --- - -class ILinkMixin { -public: - virtual ~ILinkMixin() = default; - virtual void linkChild(const NodePtr& child) = 0; - virtual void unlinkParent() = 0; - virtual LinkPtr getLink() = 0; -}; - -class INode : public ILinkMixin { -public: - ~INode() override = default; - virtual const std::string& name() const = 0; - virtual NodePtr getSelf() = 0; -}; - -class ILink { -public: - virtual ~ILink() = default; - virtual NodePtr getNode() const = 0; - virtual LinkPtr getParent() const = 0; - virtual void setParent(const LinkPtr& parent) = 0; - virtual const std::vector& getChildren() const = 0; - virtual void addChild(const LinkPtr& child) = 0; - virtual void removeChild(const LinkPtr& child) = 0; -}; - -// --- РЕАЛИЗАЦИИ LINK --- - -class BaseLink : public ILink { -public: - explicit BaseLink(NodePtr node) : owner_node_(node) {} - NodePtr getNode() const override { return owner_node_.lock(); } - LinkPtr getParent() const override { return parent_.lock(); } - void setParent(const LinkPtr& parent) override { parent_ = parent; } - const std::vector& getChildren() const override { return children_; } - void removeChild(const LinkPtr& child) override { - children_.erase(std::remove(children_.begin(), children_.end(), child), children_.end()); - } -protected: - std::vector children_; - std::weak_ptr owner_node_; - std::weak_ptr parent_; -}; - -class LeafLink : public BaseLink { -public: - using BaseLink::BaseLink; - void addChild(const LinkPtr&) override { throw std::logic_error("LeafLink cannot have children"); } -}; - -class OneToManyLink : public BaseLink { -public: - using BaseLink::BaseLink; - void addChild(const LinkPtr& child) override { children_.push_back(child); } -}; - -// --- CRTP МИКСИН-РЕАЛИЗАЦИЯ --- - -template -class LazyLinkMixin : public INode { -public: - void linkChild(const NodePtr& childNode) override { - lazyInit(); - upgradeLinkIfNeeded(); - LinkPtr childLink = childNode->getLink(); - childLink->setParent(link_); - link_->addChild(childLink); - } - - void unlinkParent() override { - lazyInit(); - LinkPtr parentLink = link_->getParent(); - if (!parentLink) return; - parentLink->removeChild(this->getLink()); - link_->setParent(nullptr); - // downgradeLinkIfPossible() здесь не нужен, т.к. узел просто отсоединяется - } - - LinkPtr getLink() override { - lazyInit(); - return link_; - } - -protected: - virtual std::shared_ptr getShared() = 0; - NodePtr getSelf() override { return getShared(); } - -private: - void lazyInit() { - if (!link_) { - link_ = std::make_shared(getSelf()); - } - } - - // ИСПРАВЛЕНО: Эта функция теперь корректно обновляет родителя - void upgradeLinkIfNeeded() { - if (!std::dynamic_pointer_cast(link_)) return; - - // Создаем новую, улучшенную связь - auto newLink = std::make_shared(getSelf()); - - // Если был родитель, уведомляем его о замене - if (auto parentLink = link_->getParent()) { - parentLink->removeChild(link_); // Удаляем старую связь - parentLink->addChild(newLink); // Добавляем новую - } - - // Переносим родителя в новую связь и заменяем старую - newLink->setParent(link_->getParent()); - link_ = newLink; - } - - // ИСПРАВЛЕНО: Эта функция теперь тоже корректно обновляет родителя - void downgradeLinkIfPossible() { - if (link_->getChildren().empty() && std::dynamic_pointer_cast(link_)) { - // Создаем новую, упрощенную связь - auto newLink = std::make_shared(getSelf()); - - // Если был родитель, уведомляем его о замене - if (auto parentLink = link_->getParent()) { - parentLink->removeChild(link_); // Удаляем старую связь - parentLink->addChild(newLink); // Добавляем новую - } - - // Переносим родителя в новую связь и заменяем старую - newLink->setParent(link_->getParent()); - link_ = newLink; - } - } - - LinkPtr link_; -}; - -// --- КОНКРЕТНЫЙ УЗЕЛ --- - -class SimpleNode : public LazyLinkMixin, - public std::enable_shared_from_this { -public: - static NodePtr create(std::string name) { - struct EnableMakeShared : public SimpleNode { - EnableMakeShared(std::string n) : SimpleNode(std::move(n)) {} - }; - return std::make_shared(std::move(name)); - } - const std::string& name() const override { return name_; } -protected: - std::shared_ptr getShared() override { - return shared_from_this(); - } -private: - friend class LazyLinkMixin; - explicit SimpleNode(std::string name) : name_(std::move(name)) {} - std::string name_; -}; - -// --- УТИЛИТА ДЛЯ ВЫВОДА --- - -void printTree(const NodePtr& startNode, int indent = 0) { - if (!startNode) return; - for (int i = 0; i < indent; ++i) std::cout << " "; - std::cout << startNode->name() << "\n"; - LinkPtr nodeLink = startNode->getLink(); - for (const auto& childLink : nodeLink->getChildren()) { - printTree(childLink->getNode(), indent + 1); - } -} - -// --- MAIN --- - -int main() { - auto root = SimpleNode::create("Root"); - auto child1 = SimpleNode::create("Child1"); - auto child2 = SimpleNode::create("Child2"); - - root->linkChild(child1); - root->linkChild(child2); - - auto subchild = SimpleNode::create("SubChild"); - child1->linkChild(subchild); - - std::cout << "Initial tree:\n"; - printTree(root); - - std::cout << "\nUnlinking Child1...\n"; - child1->unlinkParent(); - - std::cout << "\nFinal tree:\n"; - printTree(root); - - return 0; -}