iters
Сергей Маринкевич 7 months ago
parent fd34b335c1
commit 8b60fc0183

@ -27,8 +27,6 @@ class INode : public ILinkMixin {
public:
~INode() override = default;
virtual const std::string& name() const = 0;
// УБРАНО: const. Этот метод используется для получения указателя,
// который может участвовать в не-константных операциях.
virtual NodePtr getSelf() = 0;
};
@ -92,7 +90,7 @@ public:
if (!parentLink) return;
parentLink->removeChild(this->getLink());
link_->setParent(nullptr);
downgradeLinkIfPossible();
// downgradeLinkIfPossible() здесь не нужен, т.к. узел просто отсоединяется
}
LinkPtr getLink() override {
@ -101,13 +99,8 @@ public:
}
protected:
// УБРАНО: const. Возвращаем неконстантный указатель.
virtual std::shared_ptr<TFinalNode> getShared() = 0;
// УБРАНО: const. Соответствует базовому классу.
NodePtr getSelf() override {
return getShared();
}
NodePtr getSelf() override { return getShared(); }
private:
void lazyInit() {
@ -115,47 +108,63 @@ private:
link_ = std::make_shared<LeafLink>(getSelf());
}
}
// ИСПРАВЛЕНО: Эта функция теперь корректно обновляет родителя
void upgradeLinkIfNeeded() {
if (!std::dynamic_pointer_cast<LeafLink>(link_)) return;
auto oldParent = link_->getParent();
link_ = std::make_shared<OneToManyLink>(getSelf());
link_->setParent(oldParent);
// Создаем новую, улучшенную связь
auto newLink = std::make_shared<OneToManyLink>(getSelf());
// Если был родитель, уведомляем его о замене
if (auto parentLink = link_->getParent()) {
parentLink->removeChild(link_); // Удаляем старую связь
parentLink->addChild(newLink); // Добавляем новую
}
// Переносим родителя в новую связь и заменяем старую
newLink->setParent(link_->getParent());
link_ = newLink;
}
// ИСПРАВЛЕНО: Эта функция теперь тоже корректно обновляет родителя
void downgradeLinkIfPossible() {
if (link_->getChildren().empty()) {
auto oldParent = link_->getParent();
link_ = std::make_shared<LeafLink>(getSelf());
link_->setParent(oldParent);
if (link_->getChildren().empty() && std::dynamic_pointer_cast<OneToManyLink>(link_)) {
// Создаем новую, упрощенную связь
auto newLink = std::make_shared<LeafLink>(getSelf());
// Если был родитель, уведомляем его о замене
if (auto parentLink = link_->getParent()) {
parentLink->removeChild(link_); // Удаляем старую связь
parentLink->addChild(newLink); // Добавляем новую
}
// Переносим родителя в новую связь и заменяем старую
newLink->setParent(link_->getParent());
link_ = newLink;
}
}
LinkPtr link_;
};
// --- КОНКРЕТНЫЙ УЗЕЛ ---
// УБРАНО: final. Теперь от класса можно наследоваться.
class SimpleNode : public LazyLinkMixin<SimpleNode>,
public std::enable_shared_from_this<SimpleNode>
{
public std::enable_shared_from_this<SimpleNode> {
public:
static NodePtr create(std::string name) {
// Теперь эта структура может легально наследоваться от SimpleNode
struct EnableMakeShared : public SimpleNode {
EnableMakeShared(std::string n) : SimpleNode(std::move(n)) {}
};
return std::make_shared<EnableMakeShared>(std::move(name));
}
const std::string& name() const override { return name_; }
protected:
// УБРАНО: const. Теперь возвращается неконстантный shared_ptr, как и ожидается.
std::shared_ptr<SimpleNode> getShared() override {
return shared_from_this();
}
private:
friend struct std::enable_shared_from_this<SimpleNode>;
friend class LazyLinkMixin<SimpleNode>;
explicit SimpleNode(std::string name) : name_(std::move(name)) {}
std::string name_;
@ -186,11 +195,13 @@ int main() {
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;

Loading…
Cancel
Save