Понижение и копирование объекта const

#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)? т.е. переданный объект производного типа, получить объект базового типа. Передача указателя на объект через потоки кажется опасной, поскольку объект может быть уничтожен вызывающим абонентом вскоре после отправки сигнала.