#c #qt #sigabrt #dynamic-cast #descendant
#c #qt #sigabrt #динамическое приведение #потомок
Вопрос:
Мой метод получает объект в качестве параметра, и он должен быть принят как базовый тип (хотя он отправляется как производный тип). Я хочу сделать копию этого объекта и преобразовать его в производный тип, чтобы я мог вызвать метод производного типа (который изменяет свойства производного объекта).
Я возился с вариантами dynamic_cast, но не могу порадовать компилятор, ИЛИ он компилируется, и я получаю sigABRT в строке dynamic_cast (как показано ниже):
void mymethod(Base message) {
if (message.messageType() == "D") {
Derivedamp; derivedMessage = dynamic_cast<Derivedamp;>(message);
Derived derivedCopy = derivedMessage;
derivedCopy.derMethod();
В случае, если это имеет значение, mymethod — это СЛОТ Qt, который принимает сигнал через потоки. Я не думаю, что можно (или, по крайней мере, безопасно) передавать указатель на объект через потоки, поэтому я передаю по значению.
Комментарии:
1. Вероятно, существует опечатка с недоделанной строкой в
if (message.messageType() == "D) {
2. Я упростил вопрос, чтобы избавиться от ‘const’. Проблема, похоже, больше связана с понижением
3. у @George
dynamic_cast<Derivedamp;>(message);
автоматически нет UB. Это зависит от того, что известно о «сообщении». Там также нет нарезки объектов, если только типы не являются невиртуальными (что кажется маловероятным).
Ответ №1:
void mymethod(const Base message)
Если вы передаете параметр типа Base
, то тип объекта есть Base
, а не что-то еще, то есть он никогда не будет объектом производного типа.
Если вы хотите иметь полиморфизм во время выполнения, вам нужно использовать косвенное обращение. Типичным решением является передача ссылки на подобъект базового класса:
void mymethod(const Baseamp; message)
Указанная база может быть подобъектом в любом производном классе.
Комментарии:
1. Обратите внимание, что message является копией объекта, переданного в mymethod(), а не исходного объекта. Таким образом, все производные элементы не копируются. Если вы не передадите указатель или ссылку.
2. @jens — я называю mymethod объектом производного типа. Вы хотите сказать, что когда mymethod создает копию параметра ‘message’, он лишается всего производного материала и теперь становится базовым объектом? (Значит, его нельзя понизить?) Значит, никогда нельзя понизить объект, если он был получен по значению?
3. @eerorika — Я вызываю mymethod с объектом производного типа. Я не могу использовать косвенное обращение, потому что это слот Qt (добавлен в вопрос), а объект передается с использованием механизма сигналов / слотов Qt. (Который не позволяет передавать ссылки по потокам — я не думаю)
4. Да — сообщение лишено всех производных аспектов.
5. Хорошо, это объясняет причину sigabrt. Можете ли вы предложить способ сделать это (с учетом ограничения Qt signal / slot)? т.е. переданный объект производного типа, получить объект базового типа. Передача указателя на объект через потоки кажется опасной, поскольку объект может быть уничтожен вызывающим абонентом вскоре после отправки сигнала.