diff --git a/include/mixins/FabricMixin.h b/include/mixins/FabricMixin.h new file mode 100644 index 0000000..4dc078d --- /dev/null +++ b/include/mixins/FabricMixin.h @@ -0,0 +1,11 @@ +#pragma once +#include + +template +class FabricMixin { +public: + template + static std::shared_ptr create(Args&&... args) { + return std::shared_ptr(new T(std::forward(args)...)); + } +}; diff --git a/include/nodes/ComplexNode.h b/include/nodes/ComplexNode.h index 8320842..a7c2e8a 100644 --- a/include/nodes/ComplexNode.h +++ b/include/nodes/ComplexNode.h @@ -2,16 +2,20 @@ #include "nodes/BaseNode.h" #include "mixins/HierarchicalLinkMixin.h" +#include "mixins/FabricMixin.h" #include "Logger.h" /// \brief Класс сложного (составного) узла дерева. /// Может содержать несколько дочерних ComplexNode и один SimpleNode. class ComplexNode : public BaseNode, - virtual public HierarchicalLinkMixin { + virtual public HierarchicalLinkMixin, + public FabricMixin { public: ~ComplexNode() { Logger::get("ConDes").dbg(std::string("--- Complex destructor called for: ") + name_); } +private: + friend class FabricMixin; ComplexNode(std::string name) : BaseNode(std::move(name)) { Logger::get("ConDes").dbg(std::string("--- Complex constructor called for: ") + name_); } diff --git a/include/nodes/SimpleNode.h b/include/nodes/SimpleNode.h index 8f6abe1..221d9a0 100644 --- a/include/nodes/SimpleNode.h +++ b/include/nodes/SimpleNode.h @@ -2,17 +2,21 @@ #include "nodes/BaseNode.h" #include "mixins/LazyLinkMixin.h" +#include "mixins/FabricMixin.h" #include "links/OneToOneLink.h" #include "Logger.h" /// \brief Класс простого (листового) узла дерева. /// Может содержать только одного дочернего ComplexNode. class SimpleNode : public BaseNode, - virtual public LazyLinkMixin> { + virtual public LazyLinkMixin>, + public FabricMixin { public: ~SimpleNode() { Logger::get("ConDes").dbg(std::string("--- Simple destructor called for: ") + name_); } +private: + friend class FabricMixin; SimpleNode(std::string name) : BaseNode(std::move(name)) { Logger::get("ConDes").dbg(std::string("--- Simple constructor called for: ") + name_); } diff --git a/src/main.cpp b/src/main.cpp index fee4d06..4e9ec49 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,8 +39,8 @@ int main() { logger.info("Entering main scope..."); { - auto root = std::make_shared("ComplexRoot"); - auto child1 = std::make_shared("ComplexChild1"); + auto root = ComplexNode::create("ComplexRoot"); + auto child1 = ComplexNode::create("ComplexChild1"); root->linkChild(child1); @@ -49,23 +49,21 @@ int main() { std::cout << "\n"; { - auto child2 = std::make_shared("ComplexChild2"); + auto child2 = ComplexNode::create("ComplexChild2"); root->linkChild(child2); - auto subchild2 = std::make_shared("SimpleSubChild2"); + auto subchild2 = SimpleNode::create("SimpleSubChild2"); child2->linkChild(subchild2); - auto child3 = std::make_shared("ComplexChild3"); + auto child3 = ComplexNode::create("ComplexChild3"); root->linkChild(child3); - auto subchild3 = std::make_shared("SimpleSubChild3"); - child3->linkChild(subchild3); + child3->linkChild(SimpleNode::create("SimpleSubChild3")); { // Негативный сценарий 1: попытка добавить второй SimpleNode к ComplexNode try { - auto anotherSimple = std::make_shared("ShouldFail"); - child2->linkChild(anotherSimple); + child2->linkChild(SimpleNode::create("ShouldFail")); logger.err("[ERROR] Не должно было получиться добавить второй SimpleNode к ComplexNode!"); } catch (const std::logic_error& e) { logger.warn(std::string("[Ожидаемое исключение] ") + e.what()); @@ -73,14 +71,12 @@ int main() { // Негативный сценарий 2: попытка добавить ComplexNode к SimpleNode // Это допустимо: SimpleNode может иметь ComplexNode в качестве единственного ребёнка - auto goodComplex = std::make_shared("GoodComplex"); - subchild2->linkChild(goodComplex); + subchild2->linkChild(ComplexNode::create("GoodComplex")); logger.info("[OK] ComplexNode успешно добавлен к SimpleNode как единственный ребёнок."); // Негативный сценарий: попытка добавить второго ребёнка к SimpleNode try { - auto anotherSimple = std::make_shared("ShouldFail2"); - subchild2->linkChild(anotherSimple); + subchild2->linkChild(SimpleNode::create("ShouldFail2")); logger.err("[ERROR] Не должно было получиться добавить второго ребёнка к SimpleNode!"); } catch (const std::logic_error& e) { logger.warn(std::string("[Ожидаемое исключение] ") + e.what()); @@ -88,8 +84,7 @@ int main() { // Негативный сценарий: попытка добавить SimpleNode в ComplexNode, который уже содержит несколько ComplexNode-дочерних try { - auto badSimple = std::make_shared("BadSimple"); - root->linkChild(badSimple); + root->linkChild(SimpleNode::create("BadSimple")); logger.err("[ERROR] Не должно было получиться добавить SimpleNode в ComplexNode с несколькими ComplexNode-дочерними!"); } catch (const std::logic_error& e) { logger.warn(std::string("[Ожидаемое исключение] ") + e.what()); @@ -132,8 +127,7 @@ int main() { } } - auto child4 = std::make_shared("SimpleChild4"); - root->linkChild(child4); + root->linkChild(SimpleNode::create("SimpleChild4")); std::cout << "\nTree flush and link SimpleChild4:\n"; printTreeLadder(*root);