Гость
Форумы / C++ [игнор отключен] [закрыт для гостей] / Tree + полиморфный. Как кастовать в наследника? / 25 сообщений из 108, страница 1 из 5
27.05.2021, 20:03
    #40073640
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
Есть либа из одного заголовка tree.h
https://github.com/kpeeters/tree.hh
Все работает и мне удалось загнать в node полиморфный объект и прочитать.
Не удалось кастовать базовый класс к наследнику.
Это код при записи в node string
Код: plaintext
1.
2.
3.
4.
5.
tree<string>::sibling_iterator sib=tr.begin(loc);
   while(sib!=tr.end(loc)) {
     cout << (*sib) << endl;
     ++sib;
     }


При записи вместо string базового класса и наследника, я получаю базовый так:
MyBase base = *sib;
Как кастовать в наследника его?
...
Рейтинг: 0 / 0
27.05.2021, 20:07
    #40073641
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
Попутный вопрос.
Как работает поиск node в итераторе если ищется не строка а поле класса?
Сейчас при смене типа у меня find не компилится
loc=find(tr.begin(), tr.end(), "two");
...
Рейтинг: 0 / 0
27.05.2021, 20:14
    #40073646
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
Доп.вопрос.
Почему
cout << typeid(base).name() << endl;
Не выводит имя MyBase, а выводит.. (по памяти)
74namespaceMyBase12345
)) компа нет под рукой))
...
Рейтинг: 0 / 0
27.05.2021, 21:15
    #40073669
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
PetroNotC Sharp,

Кастовать в наследника не нужно. Для этого придумали виртуальные методы
...
Рейтинг: 0 / 0
27.05.2021, 21:59
    #40073677
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
Siemargl
PetroNotC Sharp,

Кастовать в наследника не нужно. Для этого придумали виртуальные методы

Я бы за. Но не вижу специфических методов наследника в IDE.
Они только у наследника.
...
Рейтинг: 0 / 0
27.05.2021, 23:06
    #40073683
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
PetroNotC Sharp,

Ну ты то умнее IDE... Или нет?
...
Рейтинг: 0 / 0
28.05.2021, 01:06
    #40073694
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
PetroNotC Sharp,

Вот, о чем тебе говорил Siemargl
Код: 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 <string>
#include "tree.hh"
#include <iostream>
#include <memory>

class Base {
public:
    virtual void Serialize(std::ostream& os) const = 0;
    virtual ~Base() {}
};

auto getTree() {
    class ChildFirst :  public Base { virtual void Serialize(std::ostream& os) const { os << "First"  << std::endl; }; };
    class ChildSecond : public Base { virtual void Serialize(std::ostream& os) const { os << "Second" << std::endl; }; };
    class ChildThird :  public Base { virtual void Serialize(std::ostream& os) const { os << "Third"  << std::endl; }; };
    tree<std::unique_ptr<Base>> mTree;

    mTree.insert(mTree.begin(), std::make_unique<ChildFirst>());
    mTree.insert(mTree.begin(), std::make_unique<ChildThird>());
    mTree.insert(mTree.begin(), std::make_unique<ChildSecond>());

    return mTree;
}

int main() {
    const auto mTree = getTree();
    for (const auto& v : mTree) {
        v->Serialize(std::cout);
    }
    return 0;
}


Код: plaintext
1.
2.
3.
Second
Third
First


PetroNotC Sharp
Попутный вопрос.
Как работает поиск node в итераторе если ищется не строка а поле класса?
Сейчас при смене типа у меня find не компилится
loc=find(tr.begin(), tr.end(), "two");
std::find_if
...
Рейтинг: 0 / 0
28.05.2021, 06:57
    #40073705
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
Спасибо. Круто.
Выше писал что мне нужен НЕ виртуальный метод в наследнике.
Вызов виртуального у меня работает. Там приведение типов не нужно.
Возможно все дело в том что я вместо
mTree.insert(... std::make_unique<ChildFirst>());
по аналогии со строкой
mTree.insert(... "abc" );
Делал
mTree.insert(... ChildFirst(123, "abc") );
Умных указателей развелось.
Доберусь до компа попробую.
...
Рейтинг: 0 / 0
28.05.2021, 06:59
    #40073707
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
Siemargl
PetroNotC Sharp,

Ну ты то умнее IDE... Или нет?
не)))))
Я к IDE отношусь с богопочтением.))
Мне нужно после точки подсказка по кастованному объекту.
...
Рейтинг: 0 / 0
28.05.2021, 07:22
    #40073713
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
авторИспользуя информацию о типах во время выполнения, можно проверить, указывает ли указатель на полный объект и можно ли безопасно выполнить приведение этого указателя, чтобы он указывал на другой объект в своей иерархии. Для выполнения этих типов приведений можно использовать оператор dynamic_cast
Вот у меня это не выходило, возможно из за статической инициализации без оператора new объекта.
std::make_unique не приходилось использовать ни разу. Каюсь.
...
Рейтинг: 0 / 0
28.05.2021, 10:07
    #40073736
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
Блин))) у меня с++11
Пробовать оператор new?
...
Рейтинг: 0 / 0
28.05.2021, 10:31
    #40073740
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
Можно пример для с11?
Ни shared_ptr, ни unique_ptr, ни new не работают.
...
Рейтинг: 0 / 0
28.05.2021, 10:43
    #40073743
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
PetroNotC Sharp
Доп.вопрос.
Почему
cout << typeid(base).name() << endl;
Не выводит имя MyBase, а выводит.. (по памяти)
74namespaceMyBase12345
)) компа нет под рукой))
пишет так
N5my15my213ClassMyE
Для
namespace my1{
namespace my2{
class ClassMy
...
Рейтинг: 0 / 0
28.05.2021, 11:01
    #40073752
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
PetroNotC Sharp

Возможно все дело в том что я вместо
mTree.insert(... std::make_unique<ChildFirst>());
по аналогии со строкой
mTree.insert(... "abc" );
Делал
mTree.insert(... ChildFirst(123, "abc") );
Умных указателей развелось.
Указатель на тип базового класса нужен для вызова виртуальных (полиморфных) методов объектов дочерних классов. Умный он или не очень - в данном контексте не так важно. make_unique появился в C++14, но и до него в C+11 была возможность инициализации умного указателя, правда, в чуть более длинной форме.
...
Рейтинг: 0 / 0
28.05.2021, 11:12
    #40073757
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
Пробовал. Не выходит. ((
А с pointer = new class не берет сама либа
...
Рейтинг: 0 / 0
28.05.2021, 11:15
    #40073758
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
PetroNotC Sharp
Пробовал. Не выходит. ((
Ошибка в 17-ой строке.
...
Рейтинг: 0 / 0
28.05.2021, 11:15
    #40073759
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
Главное, со статической инициализацией все работает. И я так понял потом кастовать в наш указатель уже поздно что ли?
Я вообще на либу подумал.
Но потом все заработало кроме получения полного класса из базового.
...
Рейтинг: 0 / 0
28.05.2021, 11:16
    #40073760
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad
PetroNotC Sharp
Пробовал. Не выходит. ((
Ошибка в 17-ой строке.
ОК чуть позже все перепроверю.
Спс.
...
Рейтинг: 0 / 0
28.05.2021, 15:10
    #40073838
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
Загрузил твой код не в Qt с 11 а в студии
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
int main() {
    const auto mTree = getTree();
    for (const auto& v : mTree) {
        v->Serialize(std::cout);
  SChildFirst* child = dynamic_cast<ChildFirst*>(v);
         child->f();
    }
    return 0;
}


Дает ошибку cannot convert from unique ptr
Как исправить?
...
Рейтинг: 0 / 0
28.05.2021, 15:55
    #40073859
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
PetroNotC Sharp,

Fix лежит на поверхности, но я не дам тебе решения, пока ты не объяснишь какую задачу ты решаешь и для каких целей тебе такая конвертация.
...
Рейтинг: 0 / 0
28.05.2021, 16:08
    #40073865
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
Ну, во первых это обычное поле data pointer в деревьях еще со времен дельфи.
Во вторых, мне конкретно в листьях дерева нужен класс ЛистДерева с бизнес данными.
А выше структура это просто классификатор.
Например, в листьях Семья с атрибутами. А дерево это адрес.
Или
....
Это банальная Модель данных повсюду.
Как поле tag в любом vcl объекте.
...
Рейтинг: 0 / 0
28.05.2021, 16:10
    #40073866
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
Раньше была Сишная конвертация)))
А теперь наворотили из за отсутствия сборщика мусора?
(про shared ptr почитал)))
...
Рейтинг: 0 / 0
28.05.2021, 16:17
    #40073868
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
Код: plaintext
1.
2.
3.
foreach (var node in tree.nodes) {
    node.Tag as ClassY).functionX()
} 


Это шарп
...
Рейтинг: 0 / 0
28.05.2021, 16:19
    #40073869
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
AmKad,
И вообще, чем дерево как коллекция отличается от списка TList?
Я же не о полиморфизме счас.
Там нельзя наследников держать?
...
Рейтинг: 0 / 0
28.05.2021, 18:08
    #40073900
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tree + полиморфный. Как кастовать в наследника?
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;
}
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Tree + полиморфный. Как кастовать в наследника? / 25 сообщений из 108, страница 1 из 5
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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