Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3 4 5   вперед  Ctrl      все
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Anatoly Moskovsky,
Я же привел пример выше с классом Семья в листьях дерева.
Как будем решать?
В не листьях требуется только строка адреса Область-Район-Город-..
Тогда базовый класс будет и адресом и семьей? Так что ли?
28 май 21, 18:28    [22328612]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Anatoly Moskovsky,
Странно что это нельзя сделать в плюсах)
22328546
28 май 21, 18:42    [22328620]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Anatoly Moskovsky,
Это как реализуете?
Картинка с другого сайта.
28 май 21, 18:51    [22328626]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
petrav
Member

Откуда:
Сообщений: 2944
Anatoly Moskovsky
PetroNotC Sharp,

Зачем вам наследование если наследники не наследуют виртуальные функции?

Лучше используйте std::vaiant с обычными значениями и не морочьте себе голову.

#include <variant>

struct A {
    void run1() { LOG_TRACE("a"); }
};
struct B {
    void run2() { LOG_TRACE("b");}
};

using Value = std::variant<A, B>;

int main()
{
    tree<Value> tree;
    auto a = tree.insert(tree.begin(), A{});
    tree.append_child(a, B{});
    for (auto&& n: tree) {
        struct Visitor {
            void operator()(A& a)
            {
                a.run1();
            }
            void operator()(B& b)
            {
                b.run2();
            }
        };
        std::visit(Visitor{}, n);
    }
    return 0;
}

Анатолий, а зачем вы здесь применили ссылку на rvalue (если я правильно выразился)?
28 май 21, 20:15    [22328664]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
petrav
Анатолий, а зачем вы здесь применили ссылку на rvalue (если я правильно выразился)?

Это идиоматический код, подходящий для любых ситуаций.
В данном случае это универсальная(universal/forwarding) ссылка (т.к. auto создает контекс вывода типа, как в шаблонах).
В зависимости от результата * итератора она станет либо rvalue либо lvalue ссылкой.
В случае если *it это не ссылка, а значение - это полезное свойство, так как auto& не примет такое значение, а просто auto может быть дорого.
Так что в generic коде - самое оно.
28 май 21, 21:35    [22328685]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
PetroNotC Sharp
Странно что это нельзя сделать в плюсах)
22328546

Если есть наследование, то выше вам уже написали - dynamic_cast решает эту же задачу.

Но это неверный дизайн если вам надо делать касты.

Я уже написал как делать - создать классы на каждый тип узла дерева и перечислить их в variant.
А потом при обходе дерева использовать std::visit для выполнения кода специфичного для каждого типа.
28 май 21, 21:41    [22328687]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Anatoly Moskovsky
Если есть наследование, то выше вам уже написали - dynamic_cast решает эту же задачу.

Я же выше написал код с ошибкой. Как убрать ошибку?

Anatoly Moskovsky
Но это неверный дизайн если вам надо делать касты.

давайте сначала уберем ошибку а потом про архитектуру и дизайн.

Anatoly Moskovsky
Я уже написал как делать - создать классы на каждый тип узла дерева и перечислить их в variant.
А потом при обходе дерева использовать std::visit для выполнения кода специфичного для каждого типа.

То есть либа выше не предусматривает приведения типа?
28 май 21, 22:00    [22328697]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
White Owl
Member

Откуда:
Сообщений: 12733
PetroNotC Sharp
Anatoly Moskovsky,
Я же привел пример выше с классом Семья в листьях дерева.
Как будем решать?
В не листьях требуется только строка адреса Область-Район-Город-..
Тогда базовый класс будет и адресом и семьей? Так что ли?
А зачем тогда в ветках (на уровне Область-Район-Город) методы для листьев (Семьи)?

Но вообще, не понимаю в чем у тебя проблема то?
Ну сделай себе вместо дерева матрешку.
class Family;
class City {
   vector<Family> families;
};
class Area {
   vector<City> cities;
};
class Region {
  vector<Area> areas;
};
А потом добавляй в эти классы объединяющие методы например:
City::dinnerTime() { 
  for_each (families.begin(), families.end(), [](Family f){f.eat();});
}
По существу это тоже самое дерево, но на каждой высоте у тебя будет именованный класс.
28 май 21, 22:20    [22328701]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
PetroNotC Sharp
Я же выше написал код с ошибкой. Как убрать ошибку?


SChildFirst* child = dynamic_cast<ChildFirst*>(v);

// cannot convert from unique ptr

Если речь про эту ошибку то - так:
ChildFirst* child = dynamic_cast<ChildFirst*>(v.get());
if (child) {
   //  ChildFirst
}
else {
  // other class
}
28 май 21, 22:21    [22328702]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Anatoly Moskovsky
PetroNotC Sharp
Я же выше написал код с ошибкой. Как убрать ошибку?


SChildFirst* child = dynamic_cast<ChildFirst*>(v);

// cannot convert from unique ptr


Если речь про эту ошибку то - так:
ChildFirst* child = dynamic_cast<ChildFirst*>(v.get());
if (child) {
   //  ChildFirst
}
else {
  // other class
}
спасибо. Ты волшебник)
28 май 21, 22:35    [22328704]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
White Owl,
- методы Семьи только в наследнике. А он в листьях дерева.
В остальных ОДИН виртуальный метод
getNodeName() - там типа адрес или район или область.

Сообщение было отредактировано: 28 май 21, 22:30
28 май 21, 22:37    [22328705]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
White Owl
По существу это тоже самое дерево, но на каждой высоте у тебя будет именованный класс.

нельзя. Это классификатор. Там все может менятся. Там не нужна строгая типизация и строгие классы.
Например, может быть "два раза город" и т.д.
То есть это чел сам строит дерево и добавляет строки прямо в узел дерева.
Главный класс это листья дерева.
28 май 21, 22:43    [22328707]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
White Owl,
То что каждая мапа это в принципе дерево я согласен)).
Но бывает удобно настоящее дерево.
С плюшками (итератор обхода всего дерева\обхода одного уровня, методы добавления и рекурсии, перемещения нод и т.д.)
http://stlplus.sourceforge.net/stlplus3/docs/ntree.html
28 май 21, 22:49    [22328708]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Siemargl
Member

Откуда: 010100
Сообщений: 6493
Anatoly Moskovsky,

std::variant это c++17, а топик хочет 11 и доку не читать =)

Сообщение было отредактировано: 28 май 21, 23:53
29 май 21, 00:01    [22328719]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
Siemargl,

В Бусте есть и для 11 ))
29 май 21, 10:50    [22328750]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Да. Желательно С++11.
Имхо буст ставить как то монструозно.
Ну а к самому типу вариант я как то отношусь с осторожностью.
Очень люблю жесткую типизацию. Чтобы все под контролем)
29 май 21, 12:30    [22328760]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
PetroNotC Sharp,

Ничего монструозного в Бусте нет.

variant - это и есть жесткая типизация.
Например если в std::visit передать перегрузки не для всех типов то просто не откомпилируется.
29 май 21, 16:09    [22328799]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Anatoly Moskovsky,
>variant - это и есть жесткая типизация.
= Variant — это специальный тип данных, который может содержать любой вид данных
Тут имхо вопрос двоякий
tree<типизацияПолиморфная>
Или
tree<типизацияТипаВариант>
Что лучше надо смотреть. Опыта такого у меня нет.
...
Я выше сказал что мне лично неудобно по многим критериям а не именно variant.
У меня Qt C++11
Для установки буст нужно разрешения заказчика.
Я этот буст вообще не юзал. Мне бы в умных указателях разобраться.
А вот дерево выше из одного файла заголовка вообще идеально.
Будет у меня 17я с удовольствием посмотрю tree variant.
Спасибо за ваш пример!
29 май 21, 16:51    [22328805]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
petrav
Member

Откуда:
Сообщений: 2944
Anatoly Moskovsky
PetroNotC Sharp,

Ничего монструозного в Бусте нет.

variant - это и есть жесткая типизация.
Например если в std::visit передать перегрузки не для всех типов то просто не откомпилируется.

Э... std::variant — это всё же нарушение всех базовых принципов ООП. Эти перегрузки — это прямой
аналог оператора switch от типа объекта. Цель полиморфизма как раз и была отходом от этого switch.
29 май 21, 17:37    [22328814]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6658
petrav
Эти перегрузки — это прямой
аналог оператора switch от типа объекта.

В отличие от switch, variant не дает пропустить обработку типов.
Это принципиальная разница.
Так что это и близко не аналог switch.
По решаемой задаче это как раз аналог полиморфизма с абстрактными методами, которые подтипы должны реализовать.
29 май 21, 18:18    [22328822]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
petrav
Цель полиморфизма как раз и была отходом от этого switch.

Цель топика не полиморфизм в чистом виде.
При полиморфном объекте НЕ виртуальные методы не вызываются.
А мне нужно вызвать и меть реально разные классы.
В принципе нужно и то и то.
И метод один на всех getTextNode() и вызвать особенности индивидуального класса.
Это не классика полиморфизма с его методом Draw()
29 май 21, 18:28    [22328824]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 53394

При этом ты упомянул Дельфи с её классикой полиморфизма в виде всеобщего предка TObject и
его методов ClassName и т.д. и т.п.

Posted via ActualForum NNTP Server 1.5

29 май 21, 18:38    [22328828]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Dimitry Sibiryakov
При этом ты упомянул Дельфи с её классикой полиморфизма в виде всеобщего предка TObject и
его методов ClassName и т.д. и т.п.
я упомянул tag и data pointer который есть везде (шарпе и дельфи).
А TObject как базовый класс это не совсем полиморфизм.
В Qt тоже есть базовый класс но полиморфизмом никто не зовет.
29 май 21, 18:55    [22328830]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 53394

PetroNotC Sharp
я упомянул tag и data pointer который есть везде (шарпе и дельфи).

И что тебе мешает в своём дереве иметь uintptr_t tag и void* data для каждой ноды?

Posted via ActualForum NNTP Server 1.5

29 май 21, 19:01    [22328831]     Ответить | Цитировать Сообщить модератору
 Re: Tree + полиморфный. Как кастовать в наследника?  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 8256
Dimitry Sibiryakov,
а топик про другое. Как кастовать на сегодня с умными указателями а не по Сишному скобками как раньше.
Или работает как раньше?
29 май 21, 19:10    [22328834]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3 4 5   вперед  Ctrl      все
Все форумы / C++ Ответить