Dynamic_cast с виртуальным наследованием вызывает нарушение прав доступа

У меня есть особая иерархия классов, которая дает сбой во время выполнения (Visual Studio 2017).

struct A{};
struct B
{
    auto f()
    {
        dynamic_cast<A *>(this);//triggers: Access violation
    }

    virtual ~B() = default;
};

struct C :virtual B, A//remove "virtual" to fix
{
    C()
    {
        f();
    }
    int a;//remove to fix
};
struct D :virtual C{};//remove "virtual" to fix

int main() 
{
    D d;
}

Вопрос такой: Это проблема кода или, скорее, ошибка компилятора?

Я пробовал множество вариантов, но ни один из них не удовлетворил меня, так как этот код мне кажется правильным.

dynamic_cast не всегда работает должным образом при вызове из конструктора, подобно тому как функции virtual не всегда делают то, что вы ожидаете.
François Andrieux 16.11.2018 22:17

@ FrançoisAndrieux Это зависит от того, чего ожидает ты! В конструкторе подобъекта невиртуальной базы без виртуальной базы виртуальные функции, dynamic_cast и все остальное ведут себя точно так же, как в конструируемом полном классе этого типа, даже с абстрактным классом, который только что завершился с недопустимым определением чистой виртуальной функции. На практике во всех реализациях все соответствует поведению всего класса: макет, значение всех vptr, поэтому формализация ожиданий проста. Это неверно, если у вас есть виртуальные базы, поскольку базовый объект не похож на законченный объект.

curiousguy 18.11.2018 04:43

@ FrançoisAndrieux В каких конкретных случаях dynamic_cast будет плохо себя вести при использовании на строящемся субъекте базового класса, где задействовано виртуальное наследование? (Конечно, dynamic_cast<T>(this) не будет использоваться с преждевременным this.)

curiousguy 18.11.2018 04:49

Выложите пожалуйста смещения подобъектов в C vs D

curiousguy 18.11.2018 07:09

"int a;//remove to fix" Я полагаю, что C::a заставляет D расти, поскольку не позволяет C быть первичным в полном D, что меняет ... что-то. Выложите пожалуйста оверхед D с C::a и без него.

curiousguy 18.11.2018 07:50

@ FrançoisAndrieux Единственные виртуальные функции, которые вы никогда не можете вызывать из конструктора, - это прямой вызов деструктора (this->~T();) и удаление деструктора (delete this;)

curiousguy 18.11.2018 08:27

@Acorn "На этот вопрос уже есть ответ здесь" Правда? Где?

curiousguy 20.11.2018 05:56

Похоже, я должен признать полиморфизм недоступным в конструкторах. Жалко, что предупреждений нет, и это легко игнорировать.

Agent Kat 28.11.2018 17:18

@Pjoter Полиморфизм отлично работает в конструкторах!

curiousguy 02.12.2018 09:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
233
0

Другие вопросы по теме