Название: [РЕШЕНО] Использование dynamic-cast Отправлено: Yegor от Май 31, 2017, 21:08 Всем здравствуйте!
На счет dynamic_cast. Его используют для того, чтобы преобразовать из указателя на базовый класс в указатель на класс-потомок. А как на счет преобразования из базового класса на класс-примесь? Который есть дальше в структуре наследования. Например, есть базовый класс. Он наследуется потомку. А тот потомок еще наследует и класс-примесь. Можно ли, имея указатель на базовый класс, преобразовать его на класс-примесь? С помощью dynamic_cast. Спасибо! Название: Re: Использование dynamic-cast Отправлено: Пантер от Май 31, 2017, 21:33 Нет, они же в разных иерархиях находятся.
Название: Re: Использование dynamic-cast Отправлено: Igors от Июнь 01, 2017, 07:35 У меня это почему-то всегда работало :), но некоторые говорят что нет - ну наверное зависит от реализации. Во всяком случае это всегда можно сделать 2-мя dynamic_cast, так точно приведет
Название: Re: Использование dynamic-cast Отправлено: __Heaven__ от Июнь 01, 2017, 07:38 Разве?
Код Компиль имеет дерево наследования и знает как с помощью смещения указателя получить указатель на вторую базу. Название: Re: Использование dynamic-cast Отправлено: Пантер от Июнь 01, 2017, 09:26 Странно, был уверен, что нельзя. Посыпаю голову пеплом.
А стандарт это регламентирует? Название: Re: Использование dynamic-cast Отправлено: __Heaven__ от Июнь 01, 2017, 09:51 sidecast, кажется, это называется
Здесь в примере это происходит http://en.cppreference.com/w/cpp/language/dynamic_cast Название: Re: Использование dynamic-cast Отправлено: Igors от Июнь 01, 2017, 09:59 Код
Код Обратите внимание что Leaf1 и Leaf2 не связаны никакими отношениями наследования. Но у меня печатает все 3 адреса разные и ненулевые А стандарт это регламентирует? Вроде нет, на усмотрение реализации Название: Re: Использование dynamic-cast Отправлено: __Heaven__ от Июнь 01, 2017, 10:32 Пример из стандарта:
Код Судя по всему, стандарт предполагает возврат 0 значения указателя при подобных кастах. Кстати, смутила строка Код А разве здесь правомерно взят адрес B? Кажется тут взят адрес А и преобразован к B. P.S.: Пантер, к вопросу об отличии reinterpret_cast и pure C cast Название: Re: Использование dynamic-cast Отправлено: __Heaven__ от Июнь 01, 2017, 10:53 Хотя, тут в примере ситуация отягощается наличием приватного наследования...
Название: Re: Использование dynamic-cast Отправлено: Igors от Июнь 01, 2017, 10:57 Кстати, смутила строка Да, bp != &d, С каст автоматом выбирает наилучший вариант приведения, поэтому я всегда считал его "expert mode" :)Код А разве здесь правомерно взят адрес B? Кажется тут взят адрес А и преобразован к B. Судя по всему, стандарт предполагает возврат 0 значения указателя при подобных кастах. Хз, в справочнике пример sidecast с классами A. B, D. Повторюсь - у меня это всегда работало, но тут (уже много лет назад) один паренек проверил мой пример и сказал что нет - ну я ему поверил, выглядел он прилично :)По идее раскрутить все "дерево" можно, т.к. типы идентифицируются, напр для примера выше Код Эти 2 экземпляра имеют один тип но разные VMT, т.е. второй знает что он часть Tree (а не сам по себе) Название: Re: Использование dynamic-cast Отправлено: Авварон от Июнь 01, 2017, 13:01 Странно, был уверен, что нельзя. Посыпаю голову пеплом. А стандарт это регламентирует? Уволен! Название: Re: Использование dynamic-cast Отправлено: Авварон от Июнь 01, 2017, 13:12 Пример из стандарта: Код Судя по всему, стандарт предполагает возврат 0 значения указателя при подобных кастах. Кстати, смутила строка Код А разве здесь правомерно взят адрес B? Кажется тут взят адрес А и преобразован к B. P.S.: Пантер, к вопросу об отличии reinterpret_cast и pure C cast Данный пример и не будет работать, потому что Код: B* bp1 = (B*)&d; Угадайте почему Название: Re: Использование dynamic-cast Отправлено: Авварон от Июнь 01, 2017, 13:17 А не, был не прав. В дебрях виртуального наследования, класс А в памяти лежит ПОСЛЕ класса B. Тогда непонятно, почему он не видит vtable.
Судя по всему, динамик каст проверяет приватность наследования, других причин не вижу. Название: Re: Использование dynamic-cast Отправлено: __Heaven__ от Июнь 01, 2017, 13:18 Так а что угадывать? :)
Я же выше написал, что c++ преобразование в отличии от pure c делает смещение с учётом порядка наследования. Название: Re: Использование dynamic-cast Отправлено: __Heaven__ от Июнь 01, 2017, 13:19 Виртуальное наследование лежит последним??
Название: Re: Использование dynamic-cast Отправлено: Авварон от Июнь 01, 2017, 13:20 Так а что угадывать? :) Я же выше написал, что c++ преобразование в отличии от pure c делает смещение с учётом порядка наследования. То, что вы оказались неправы:) Я тоже думал, что берется адрес А, но это не так: Код: qDebug() << quintptr(&d); Код: 140735028670000 Название: Re: Использование dynamic-cast Отправлено: Авварон от Июнь 01, 2017, 13:21 Виртуальное наследование лежит последним?? В данном случае, да. Интересно, как в случае множественного. Название: Re: Использование dynamic-cast Отправлено: Авварон от Июнь 01, 2017, 13:26 В данном случае, да. Интересно, как в случае множественного. Да, все кладутся в конец в порядке наследования. Код: class D : virtual public A, virtual private B, private C Код: 140730504186864 // d Ну и да: Код: class D : virtual public A, private B // сайд-каст не работает Название: Re: Использование dynamic-cast Отправлено: __Heaven__ от Июнь 01, 2017, 13:30 Цитировать Да, все кладутся в конец в порядке наследования. Точно? Я вижу несколько другую картину.Название: Re: Использование dynamic-cast Отправлено: ViTech от Июнь 01, 2017, 13:59 Цитировать Да, все кладутся в конец в порядке наследования. Точно? Я вижу несколько другую картину.Думаю не стоит на этом заморачиваться. Разные компиляторы могут по разному vtable и данные объектов создавать и хранить, это уже их головная боль. Разработчикам главное понимать, как dynamic_cast по стандарту работать должен. Название: Re: Использование dynamic-cast Отправлено: Igors от Июнь 01, 2017, 14:41 Так а что угадывать? :) С-каст сделает то же самое для приведения "по вертикали", вот sidecross оно не потянетЯ же выше написал, что c++ преобразование в отличии от pure c делает смещение с учётом порядка наследования. Думаю не стоит на этом заморачиваться. Разные компиляторы могут по разному vtable и данные объектов создавать и хранить, это уже их головная боль. Разработчикам главное понимать, как dynamic_cast по стандарту работать должен. Согласен, любое приведение легко разложить на "вертикальные", они должны работать железно. Ни к чему искать ненужных приключенийНазвание: Re: Использование dynamic-cast Отправлено: Авварон от Июнь 01, 2017, 14:43 По стандарту side cast разрешен. Например, можно кастить один интерфейс к другому.
Или проверять, реализует ли данный QObject такой-то интерфейс. Название: Re: Использование dynamic-cast Отправлено: Yegor от Июнь 02, 2017, 16:16 Всем спасибо, кто откликнулся!
|