Russian Qt Forum

Программирование => С/C++ => Тема начата: Disa от Февраль 19, 2013, 21:53



Название: Срезка или нет
Отправлено: Disa от Февраль 19, 2013, 21:53
Добрый вечер.

Восполняю свои пробелы по полиморфизму :)

Есть класс, который наследуется от класса, умеющего возвращать детей и родителя. Этот класс естессно содержит новые методы и члены.

Вопрос, если я использую addChildren, не перегружая его а потом от этого children'а, parent() - будет происходить срезка или нет? Ну то есть он мне вернет именно мой класс с моими данными?

Спасибо.


Название: Re: Срезка или нет
Отправлено: ViTech от Февраль 19, 2013, 22:53
В run-time вернет, но в compile-time вы до него не дотянетесь, без преобразования типов. Сделайте наследника от QObject и посмотрите, как это бывает. Вся функциональность по детям-родителям в нем уже есть.


Название: Re: Срезка или нет
Отправлено: Disa от Февраль 19, 2013, 22:58
Цитировать
В run-time вернет, но в compile-time вы до него не дотянетесь, без преобразования типов

Ну это-то как раз не проблема, за правильностью типов я проследить могу, мне главное чтобы поля не пропали :) Ну ладно, видимо придется завтра тестовые классы писать.


Название: Re: Срезка или нет
Отправлено: ViTech от Февраль 19, 2013, 23:14
Такая штука, как "c++ virtual covariant", может пригодиться в подобных случаях.


Название: Re: Срезка или нет
Отправлено: Disa от Февраль 20, 2013, 01:13
Спасибо, почитаю.

PS: С института слово ковариантный заставляет меня думать об МСС, Теории пластичности и тензорах. Ровно так же, как и энтропия в машинлернинге :)


Название: Re: Срезка или нет
Отправлено: lit-uriy от Февраль 21, 2013, 09:57
>>будет происходить срезка или нет?
А что это за термин такой - "Срезка"?


Название: Re: Срезка или нет
Отправлено: Disa от Февраль 21, 2013, 13:10
Термин встречал во 2ом издании у Страуструпа. Иногда называется еще "расщепление".

C RSDN'а:
Цитировать
Коротко — в производном классе могут быть определены дополнительные поля. Во время присваивания при преобразовании по принципу подстановки "лишние поля в объект базового класса. естественно, не попадают.

Чтобы понять, в чем дело, обратимся к классам точек. Рассмотрим простой пример с двумерными и трехмерными точками.
Point3D b(1,2,3);
Point2D a = b;            // подстановка в конструкторе копирования - срезка
a = b;                    // подстановка в присваивании - срезка

Работает принцип подстановки, однако нас поджидает неприятность: так как базовый класс ничего не знает о своих наследниках, то в переменную a копируется только Point2D-часть трехмерной точки. Этот эффект называется срезкой [Страуструп] или расщеплением [Брюс Эккель]; он частенько приводит к ошибкам. Например, при передаче параметра по значению, как мы знаем, работает конструктор копирования, поэтому в таких случаях тоже может произойти срезка.

Ну вот собственно я уже нашел ответ на свой вопрос, что при передачи по ссылке или указателю срезки не бывает. 


Название: Re: Срезка или нет
Отправлено: Igors от Февраль 21, 2013, 13:26
Ну вот собственно я уже нашел ответ на свой вопрос, что при передачи по ссылке или указателю срезки не бывает. 
А без всякого чтения это было не так уж очевидно?  :)


Название: Re: Срезка или нет
Отправлено: Disa от Февраль 21, 2013, 13:32
Ну мне в Си++ часто многие вещи не очевидны, я помню когда начинал программировать только меня жутко удивляло (это мало сказано), что побитовый сдвиг выводит сообщение на экран, а итераторы работаю в циклах быстрее когда ++ префиксный.