From 55ef99c848583e886dcf19b3f1229d2d03046b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=9C=D0=B0=D1=80?= =?UTF-8?q?=D0=B8=D0=BD=D0=BA=D0=B5=D0=B2=D0=B8=D1=87?= Date: Wed, 23 Jul 2025 17:44:25 +0700 Subject: [PATCH] unlink the links --- include/ifaces/ILink.h | 17 ++++++++--------- include/ifaces/ILinkMixin.h | 9 +++++++-- include/ifaces/INode.h | 2 ++ include/links/BaseLink.h | 26 ++++++++++++++------------ include/links/OneToManyLink.h | 7 ++++--- include/mixins/BaseLinkMixin.h | 19 ++++++++----------- include/mixins/LazyLinkMixin.h | 6 ++++-- include/nodes/BaseNode.h | 4 ++-- include/nodes/SimpleNode.h | 7 +++++-- src/main.cpp | 5 ++++- 10 files changed, 58 insertions(+), 44 deletions(-) diff --git a/include/ifaces/ILink.h b/include/ifaces/ILink.h index f2927b3..844a517 100644 --- a/include/ifaces/ILink.h +++ b/include/ifaces/ILink.h @@ -1,17 +1,16 @@ #pragma once #include #include -#include "ifaces/INode.h" - -using LinkPtr = std::shared_ptr; +#include "ifaces/ILinkMixin.h" +template class ILink { public: virtual ~ILink() = default; - virtual NodePtr getNode() const = 0; - virtual NodePtr getParent() const = 0; - virtual void setParent(const NodePtr& parent) = 0; - virtual const std::vector& getChildren() const = 0; - virtual void addChild(const NodePtr& child) = 0; - virtual void removeChild(const NodePtr& child) = 0; + virtual std::shared_ptr getNode() const = 0; + virtual std::shared_ptr getParent() const = 0; + virtual void setParent(const std::shared_ptr& parent) = 0; + virtual const std::vector>& getChildren() const = 0; + virtual void addChild(const std::shared_ptr& child) = 0; + virtual void removeChild(const std::shared_ptr& child) = 0; }; diff --git a/include/ifaces/ILinkMixin.h b/include/ifaces/ILinkMixin.h index eecc108..03f63c4 100644 --- a/include/ifaces/ILinkMixin.h +++ b/include/ifaces/ILinkMixin.h @@ -1,11 +1,16 @@ #pragma once #include -#include "decls.h" +#include "ifaces/ILink.h" + +class ILinkMixin; + +using MixinPtr = std::shared_ptr; +using LinkPtr = std::shared_ptr>; class ILinkMixin { public: virtual ~ILinkMixin() = default; - virtual void linkChild(const NodePtr& child) = 0; + virtual void linkChild(const MixinPtr& child) = 0; virtual void unlinkParent() = 0; virtual LinkPtr getLink() = 0; }; diff --git a/include/ifaces/INode.h b/include/ifaces/INode.h index 6692c38..fa67972 100644 --- a/include/ifaces/INode.h +++ b/include/ifaces/INode.h @@ -2,6 +2,8 @@ #include "ifaces/ILinkMixin.h" #include +class INode; + using NodePtr = std::shared_ptr; class INode : public virtual ILinkMixin { diff --git a/include/links/BaseLink.h b/include/links/BaseLink.h index c6839c3..b60d1b4 100644 --- a/include/links/BaseLink.h +++ b/include/links/BaseLink.h @@ -1,16 +1,18 @@ #pragma once -#include "ifaces/ILink.h" -#include "ifaces/INode.h" +#include #include -class BaseLink : public ILink { +#include "ifaces/ILink.h" + +template +class BaseLink : public ILink { public: - explicit BaseLink(NodePtr node) : owner_node_(node) {} - NodePtr getNode() const override { return owner_node_.lock(); } - NodePtr getParent() const override { return parent_.lock(); } - void setParent(const NodePtr& parent) override { parent_ = parent; } - const std::vector& getChildren() const override { return children_; } - void removeChild(const NodePtr& child) override { + BaseLink(std::shared_ptr node) : owner_node_(node) {} + std::shared_ptr getNode() const override { return owner_node_.lock(); } + std::shared_ptr getParent() const override { return parent_.lock(); } + void setParent(const std::shared_ptr& parent) override { parent_ = parent; } + const std::vector>& getChildren() const override { return children_; } + void removeChild(const std::shared_ptr& child) override { children_.erase(std::remove(children_.begin(), children_.end(), child), children_.end()); } @@ -18,7 +20,7 @@ public: std::cout << "--- Destructor called for: " << "BaseLink" << "\n"; } protected: - std::vector children_; - std::weak_ptr owner_node_; - std::weak_ptr parent_; + std::vector> children_; + std::weak_ptr owner_node_; + std::weak_ptr parent_; }; diff --git a/include/links/OneToManyLink.h b/include/links/OneToManyLink.h index 1e65957..bb18308 100644 --- a/include/links/OneToManyLink.h +++ b/include/links/OneToManyLink.h @@ -1,8 +1,9 @@ #pragma once #include "links/BaseLink.h" -class OneToManyLink : public BaseLink { +template +class OneToManyLink : public BaseLink { public: - using BaseLink::BaseLink; - void addChild(const NodePtr& child) override { children_.push_back(child); } + OneToManyLink(std::shared_ptr e) : BaseLink(e) {} + void addChild(const std::shared_ptr& child) override { this->children_.push_back(child); } }; diff --git a/include/mixins/BaseLinkMixin.h b/include/mixins/BaseLinkMixin.h index 8e50949..299cfe4 100644 --- a/include/mixins/BaseLinkMixin.h +++ b/include/mixins/BaseLinkMixin.h @@ -1,26 +1,23 @@ #pragma once #include -#include "ifaces/INode.h" -#include "ifaces/ILinkMixin.h" -#include "links/LeafLink.h" -#include "links/OneToManyLink.h" #include +#include "ifaces/ILinkMixin.h" + class BaseLinkMixin : public virtual ILinkMixin, - public virtual INode, - public std::enable_shared_from_this { + public std::enable_shared_from_this { public: - void linkChild(const NodePtr& childNode) override { - LinkPtr childLink = childNode->getLink(); + void linkChild(const MixinPtr& child) override { + LinkPtr childLink = child->getLink(); childLink->setParent(getNode()); - getLink()->addChild(childNode); + getLink()->addChild(child); } void unlinkParent() override { LinkPtr link = getLink(); - NodePtr parent = link->getParent(); + MixinPtr parent = link->getParent(); if (!parent) throw std::logic_error("Have no parent!"); @@ -35,7 +32,7 @@ public: } protected: - NodePtr getNode() { + MixinPtr getNode() { return shared_from_this(); } }; diff --git a/include/mixins/LazyLinkMixin.h b/include/mixins/LazyLinkMixin.h index a0f6dac..25765f2 100644 --- a/include/mixins/LazyLinkMixin.h +++ b/include/mixins/LazyLinkMixin.h @@ -19,14 +19,16 @@ public: return this->link_; } + LazyLinkMixin() {} + ~LazyLinkMixin() override { std::cout << "--- Destructor called for: " << "LazyLinkMixin" << "\n"; } protected: void lazyInit() { - if (!this->link_) { - this->link_ = std::make_shared( + if (!link_) { + link_ = std::make_shared( BaseLinkMixin::getNode()); } } diff --git a/include/nodes/BaseNode.h b/include/nodes/BaseNode.h index b89eade..1c9e9dc 100644 --- a/include/nodes/BaseNode.h +++ b/include/nodes/BaseNode.h @@ -1,8 +1,8 @@ #pragma once -#include "mixins/LazyLinkMixin.h" -#include "ifaces/INode.h" #include +#include "ifaces/INode.h" + class BaseNode : public virtual INode { public: BaseNode(std::string name) : name_(std::move(name)) { diff --git a/include/nodes/SimpleNode.h b/include/nodes/SimpleNode.h index 1f52fe7..e225ddd 100644 --- a/include/nodes/SimpleNode.h +++ b/include/nodes/SimpleNode.h @@ -1,9 +1,12 @@ #pragma once -#include "nodes/BaseNode.h" #include +#include "nodes/BaseNode.h" +#include "mixins/LazyLinkMixin.h" +#include "links/OneToManyLink.h" + class SimpleNode : public BaseNode, - public LazyLinkMixin { + virtual public LazyLinkMixin> { public: ~SimpleNode() { std::cout << "--- Simple destructor called for: " << name_ << "\n"; diff --git a/src/main.cpp b/src/main.cpp index 26d4771..9321e10 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,9 @@ #include "nodes/SimpleNode.h" #include -void printTree(const NodePtr& startNode, int indent = 0) { +void printTree(const MixinPtr& start, int indent = 0) { + if (!start) return; + auto startNode = std::dynamic_pointer_cast(start); if (!startNode) return; for (int i = 0; i < indent; ++i) std::cout << " "; std::cout << startNode->name() << "\n"; @@ -47,6 +49,7 @@ int main() { child1->unlinkParent(); std::cout << "\nTree after unlink:\n\n\n"; printTree(root); + std::cout << "\n\n"; } std::cout << "\nTree after scope out:\n\n\n";