Dynamic_cast на не полиморфных типах - PullRequest
0 голосов
/ 04 сентября 2018

Я могу понять, почему dynamic_cast работает в этом случае:

#include <iostream>

struct A{
    virtual ~A() = default;
};

struct B {
    virtual ~B() = default;
};

struct C : A, B{};

void f(const A &a) {
    if(auto p = dynamic_cast<const B*>(&a))
        std::cout << "a is a B" << std::endl;
}

int main() {
    f(C{});

    return 0;
}

Но почему, если вы удалите полиморфизм из B, он все равно будет работать:

#include <iostream>

struct A{
    virtual ~A() = default;
};

struct B {
};

struct C : A, B{};

void f(const A &a) {
    if(auto p = dynamic_cast<const B*>(&a))
        std::cout << "a is a B" << std::endl;
}

int main() {
    f(C{});

    return 0;
}

Это потому, что dynamic_cast должен знать только, что реальный тип объекта, который вы даете, имеет параметр (как это сделал бы dynamic_cast<void*> / typeid), и после того, как он знает реальный тип, он знает, является ли тип производным от не полиморфная основа?

1 Ответ

0 голосов
/ 04 сентября 2018

Согласно Стандарту ( [expr.dynamic.cast] p6 ), этот объект должен иметь полиморфный тип, а не тот, к которому вы пытаетесь привести.

И это абсолютно логично, если подумать. dynamic_cast требуется некоторая информация для приведения (RTTI), и эта информация связана с полиморфными типами. Так что не имеет значения, являются ли родители типа полиморфными или нет, информация об этом классе прямо здесь. Вам не нужно знать RTTI класса другого, чтобы наложить этот объект на него. Вам просто нужно знать, действительно ли этот объект связан с тем, во что вы хотите его преобразовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...