powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / C++ [игнор отключен] [закрыт для гостей] / Tree + полиморфный. Как кастовать в наследника?
25 сообщений из 108, страница 2 из 5
Tree + полиморфный. Как кастовать в наследника?
    #40073913
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
Я же привел пример выше с классом Семья в листьях дерева.
Как будем решать?
В не листьях требуется только строка адреса Область-Район-Город-..
Тогда базовый класс будет и адресом и семьей? Так что ли?
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073918
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
Странно что это нельзя сделать в плюсах)
22328546
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073921
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
Это как реализуете?
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073943
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
PetroNotC Sharp,

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

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
#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 (если я правильно выразился)?
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073958
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Анатолий, а зачем вы здесь применили ссылку на rvalue (если я правильно выразился)?

Это идиоматический код, подходящий для любых ситуаций.
В данном случае это универсальная(universal/forwarding) ссылка (т.к. auto создает контекс вывода типа, как в шаблонах).
В зависимости от результата * итератора она станет либо rvalue либо lvalue ссылкой.
В случае если *it это не ссылка, а значение - это полезное свойство, так как auto& не примет такое значение, а просто auto может быть дорого.
Так что в generic коде - самое оно.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073960
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
Странно что это нельзя сделать в плюсах)
22328546

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

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

Я уже написал как делать - создать классы на каждый тип узла дерева и перечислить их в variant.
А потом при обходе дерева использовать std::visit для выполнения кода специфичного для каждого типа.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073968
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Если есть наследование, то выше вам уже написали - dynamic_cast решает эту же задачу.

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

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

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

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

То есть либа выше не предусматривает приведения типа?
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073972
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
Anatoly Moskovsky,
Я же привел пример выше с классом Семья в листьях дерева.
Как будем решать?
В не листьях требуется только строка адреса Область-Район-Город-..
Тогда базовый класс будет и адресом и семьей? Так что ли?
А зачем тогда в ветках (на уровне Область-Район-Город) методы для листьев (Семьи)?

Но вообще, не понимаю в чем у тебя проблема то?
Ну сделай себе вместо дерева матрешку.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
class Family;
class City {
   vector<Family> families;
};
class Area {
   vector<City> cities;
};
class Region {
  vector<Area> areas;
};

А потом добавляй в эти классы объединяющие методы например:
Код: plaintext
1.
2.
3.
City::dinnerTime() { 
  for_each (families.begin(), families.end(), [](Family f){f.eat();});
}

По существу это тоже самое дерево, но на каждой высоте у тебя будет именованный класс.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073973
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
Я же выше написал код с ошибкой. Как убрать ошибку?


Код: plaintext
1.
2.
3.
SChildFirst* child = dynamic_cast<ChildFirst*>(v);

// cannot convert from unique ptr


Если речь про эту ошибку то - так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
ChildFirst* child = dynamic_cast<ChildFirst*>(v.get());
if (child) {
   //  ChildFirst
}
else {
  // other class
}
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073974
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
PetroNotC Sharp
Я же выше написал код с ошибкой. Как убрать ошибку?


Код: plaintext
1.
2.
3.
SChildFirst* child = dynamic_cast<ChildFirst*>(v);

// cannot convert from unique ptr



Если речь про эту ошибку то - так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
ChildFirst* child = dynamic_cast<ChildFirst*>(v.get());
if (child) {
   //  ChildFirst
}
else {
  // other class
}

спасибо. Ты волшебник)
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073975
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl,
- методы Семьи только в наследнике. А он в листьях дерева.
В остальных ОДИН виртуальный метод
getNodeName() - там типа адрес или район или область.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073976
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl
По существу это тоже самое дерево, но на каждой высоте у тебя будет именованный класс.

нельзя. Это классификатор. Там все может менятся. Там не нужна строгая типизация и строгие классы.
Например, может быть "два раза город" и т.д.
То есть это чел сам строит дерево и добавляет строки прямо в узел дерева.
Главный класс это листья дерева.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073977
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl,
То что каждая мапа это в принципе дерево я согласен)).
Но бывает удобно настоящее дерево.
С плюшками (итератор обхода всего дерева\обхода одного уровня, методы добавления и рекурсии, перемещения нод и т.д.)
http://stlplus.sourceforge.net/stlplus3/docs/ntree.html
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40073985
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

std::variant это c++17, а топик хочет 11 и доку не читать =)
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074005
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Siemargl,

В Бусте есть и для 11 ))
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074013
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да. Желательно С++11.
Имхо буст ставить как то монструозно.
Ну а к самому типу вариант я как то отношусь с осторожностью.
Очень люблю жесткую типизацию. Чтобы все под контролем)
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074044
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp,

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

variant - это и есть жесткая типизация.
Например если в std::visit передать перегрузки не для всех типов то просто не откомпилируется.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074048
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
>variant - это и есть жесткая типизация.
= Variant — это специальный тип данных, который может содержать любой вид данных
Тут имхо вопрос двоякий
tree<типизацияПолиморфная>
Или
tree<типизацияТипаВариант>
Что лучше надо смотреть. Опыта такого у меня нет.
...
Я выше сказал что мне лично неудобно по многим критериям а не именно variant.
У меня Qt C++11
Для установки буст нужно разрешения заказчика.
Я этот буст вообще не юзал. Мне бы в умных указателях разобраться.
А вот дерево выше из одного файла заголовка вообще идеально.
Будет у меня 17я с удовольствием посмотрю tree variant.
Спасибо за ваш пример!
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074053
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
PetroNotC Sharp,

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

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

Э... std::variant — это всё же нарушение всех базовых принципов ООП. Эти перегрузки — это прямой
аналог оператора switch от типа объекта. Цель полиморфизма как раз и была отходом от этого switch.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074060
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Эти перегрузки — это прямой
аналог оператора switch от типа объекта.

В отличие от switch, variant не дает пропустить обработку типов.
Это принципиальная разница.
Так что это и близко не аналог switch.
По решаемой задаче это как раз аналог полиморфизма с абстрактными методами, которые подтипы должны реализовать.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074062
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Цель полиморфизма как раз и была отходом от этого switch.

Цель топика не полиморфизм в чистом виде.
При полиморфном объекте НЕ виртуальные методы не вызываются.
А мне нужно вызвать и меть реально разные классы.
В принципе нужно и то и то.
И метод один на всех getTextNode() и вызвать особенности индивидуального класса.
Это не классика полиморфизма с его методом Draw()
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074064
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При этом ты упомянул Дельфи с её классикой полиморфизма в виде всеобщего предка TObject и
его методов ClassName и т.д. и т.п.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074066
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
При этом ты упомянул Дельфи с её классикой полиморфизма в виде всеобщего предка TObject и
его методов ClassName и т.д. и т.п.
я упомянул tag и data pointer который есть везде (шарпе и дельфи).
А TObject как базовый класс это не совсем полиморфизм.
В Qt тоже есть базовый класс но полиморфизмом никто не зовет.
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074067
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpя упомянул tag и data pointer который есть везде (шарпе и дельфи).

И что тебе мешает в своём дереве иметь uintptr_t tag и void* data для каждой ноды?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Tree + полиморфный. Как кастовать в наследника?
    #40074070
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,
а топик про другое. Как кастовать на сегодня с умными указателями а не по Сишному скобками как раньше.
Или работает как раньше?
...
Рейтинг: 0 / 0
25 сообщений из 108, страница 2 из 5
Форумы / C++ [игнор отключен] [закрыт для гостей] / Tree + полиморфный. Как кастовать в наследника?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]