Size: a a a

2021 March 11

YS

Yaroslav Syrytsia in pro.cxx
Пашечка
Ну, как вариант вынести инициализацию и старт тредов из конструктора в метод Initialize.
Да, этот вариант сейчас сделал, работает. Но может есть способы проще :)
источник

П

Пашечка in pro.cxx
Yaroslav Syrytsia
Да, этот вариант сейчас сделал, работает. Но может есть способы проще :)
Имхо это самый простой и понятный способ и есть)
источник

YS

Yaroslav Syrytsia in pro.cxx
Пашечка
Имхо это самый простой и понятный способ и есть)
Понял, спасибо )
источник

AR

Alexandr Rudalev in pro.cxx
Yaroslav Syrytsia
Привет! А подскажите сишнику, про эти ваши Base/Derived классы и pure virtual method called. Вот есть у меня базовый класс, пусть будет Base, в котом есть virtual void event_handler(Event &ev) = 0. И есть другой класс, пусть будет Derived, который собственно и содержит реализацию этого метода. Что хочу - позвать из Base класса этот метод, но иногда оно падает с ошибкой как выше.
Я подозреваю это случается потому, что Derived класс не успел выполнить свой конструктор, а Base класс уже позвал его метод (т.к. там еще и std::thread, да). И получается то самое "никогда не вызывайте виртуальные методы из конструктора/деструктора"
Вопрос: как бы это все правильно разрулить ? Может, добавить какой-то atomic флаг который сказал бы, что инициализация прошла, или я вообще не прав тут ? :)
Лучше тогда сделай статический метод Derive::build, который проинициализирует всё что надо и вернут std::unique_ptr<Base>. Тогда пользоваться будет удобнее (один вызов, вместо двух)
источник

YS

Yaroslav Syrytsia in pro.cxx
Хм, не уверен, что это будет сильно удобно. Сейчас оно у меня вот так:
Derive d;
d.init();
d.do_something(); // это тоже pure virtual

И таких вот Derive штук 10, с разными реализациями. В случае с Derive::build мне нужно будет в каждой новой реализации добавить вот этот build. Или я что-то не так понял ? :)
источник

DU

Dmitry Ulyumdzhiev in pro.cxx
Yaroslav Syrytsia
Хм, не уверен, что это будет сильно удобно. Сейчас оно у меня вот так:
Derive d;
d.init();
d.do_something(); // это тоже pure virtual

И таких вот Derive штук 10, с разными реализациями. В случае с Derive::build мне нужно будет в каждой новой реализации добавить вот этот build. Или я что-то не так понял ? :)
а можешь пояснить, зачем тебе в такой ситуации virtual?
источник

YS

Yaroslav Syrytsia in pro.cxx
Dmitry Ulyumdzhiev
а можешь пояснить, зачем тебе в такой ситуации virtual?
У меня есть базовый класс, Base, который создает поток (std::jthread) и содержит некоторую логику (типа, предварительной настройки, коннекторы, etc). И дальше есть разные классы, которые реализуют event_handler(), и этот метод вызывается из Base класса (его потока). Вообще, сама задача в том, что бы на каждую сущность был свой обработчик событий
источник

YS

Yaroslav Syrytsia in pro.cxx
например, вот приходит из вне, сделай мне XXX, и в зависимости от реализации, оно делает это разными способами и реагирует по разному
источник

AR

Alexandr Rudalev in pro.cxx
А init у тебя тоже виртуальный?
источник

AF

Aidar Fattakhov in pro.cxx
Yaroslav Syrytsia
Привет! А подскажите сишнику, про эти ваши Base/Derived классы и pure virtual method called. Вот есть у меня базовый класс, пусть будет Base, в котом есть virtual void event_handler(Event &ev) = 0. И есть другой класс, пусть будет Derived, который собственно и содержит реализацию этого метода. Что хочу - позвать из Base класса этот метод, но иногда оно падает с ошибкой как выше.
Я подозреваю это случается потому, что Derived класс не успел выполнить свой конструктор, а Base класс уже позвал его метод (т.к. там еще и std::thread, да). И получается то самое "никогда не вызывайте виртуальные методы из конструктора/деструктора"
Вопрос: как бы это все правильно разрулить ? Может, добавить какой-то atomic флаг который сказал бы, что инициализация прошла, или я вообще не прав тут ? :)
в конструкторе нельзя вызывать виртуальные функции
источник

AF

Aidar Fattakhov in pro.cxx
Yaroslav Syrytsia
У меня есть базовый класс, Base, который создает поток (std::jthread) и содержит некоторую логику (типа, предварительной настройки, коннекторы, etc). И дальше есть разные классы, которые реализуют event_handler(), и этот метод вызывается из Base класса (его потока). Вообще, сама задача в том, что бы на каждую сущность был свой обработчик событий
почему event handler это метод?
источник

AF

Aidar Fattakhov in pro.cxx
почему это не поле?
источник

YS

Yaroslav Syrytsia in pro.cxx
Aidar Fattakhov
почему это не поле?
Мне показалось, так удобней
источник

AF

Aidar Fattakhov in pro.cxx
будешь на каждый чих создавать класс как в джаве?
источник

YS

Yaroslav Syrytsia in pro.cxx
Я бы сказал, на каждую сущность - свой класс и свою логику. Время жизни класса может быть от 10 минут до нескольких месяцев
источник

AF

Aidar Fattakhov in pro.cxx
у класса нет времени жизни
источник

AF

Aidar Fattakhov in pro.cxx
оно есть у объекта
источник

YS

Yaroslav Syrytsia in pro.cxx
ладно, инстанс, ок )
источник

IZ

Ilia Zviagin in pro.cxx
Yaroslav Syrytsia
Привет! А подскажите сишнику, про эти ваши Base/Derived классы и pure virtual method called. Вот есть у меня базовый класс, пусть будет Base, в котом есть virtual void event_handler(Event &ev) = 0. И есть другой класс, пусть будет Derived, который собственно и содержит реализацию этого метода. Что хочу - позвать из Base класса этот метод, но иногда оно падает с ошибкой как выше.
Я подозреваю это случается потому, что Derived класс не успел выполнить свой конструктор, а Base класс уже позвал его метод (т.к. там еще и std::thread, да). И получается то самое "никогда не вызывайте виртуальные методы из конструктора/деструктора"
Вопрос: как бы это все правильно разрулить ? Может, добавить какой-то atomic флаг который сказал бы, что инициализация прошла, или я вообще не прав тут ? :)
Похоже на то, да.

А разрулить — не зови event_handler(Event &ev) в конструкторе, и всего делов.
источник

IZ

Ilia Zviagin in pro.cxx
Dmitry Ulyumdzhiev
а можешь пояснить, зачем тебе в такой ситуации virtual?
Очевидно, что бы в наследниках переопределить этот метод...
источник