2016-03-01 3 views
4

С классами B и производного классом D:Причина, почему dynamic_cast не работает с не полиморфными типами

class B { 
    int b; 
}; 


class D : public B { 
    int d; 
}; 


D* d = new D(); 
B* b = dynamic_cast<B*>(d); 

выше будет работать нормально — это просто приведение к базовому типу. Мы уверены, что все, что указывает b, имеет объект класса B (суб).

Однако

B* b = new D(); 
D* d = dynamic_cast<D*>(b); 

не будет компилировать, хотя b указывает на правильный D экземпляра — поскольку базовый класс не является полиморфным. Поэтому добавление только одного пустого виртуального метода решит проблему.

Важный вопрос, почему C++ требует типа источника полиморфных? Единственное объяснение, которое я нашел, это this, но он просто утверждает, что «потому что так оно реализовано внутренне» - по крайней мере, на моих глазах). У людей, которые спроектировали dynamic_cast, возможно, были и другие причины - что это было?

+0

Я не вижу ничего динамически полиморфный. В базовом классе вы потеряли хотя бы «виртуальный» деструктор. –

+1

Пожалуйста, используйте компилятор, прежде чем отправлять код с ошибками. –

+1

@ DieterLücking Достаточно, но точный код здесь не является существенной. Я бы сказал, этого было достаточно, чтобы продемонстрировать намерение. – Angew

ответ

4

Потому что нет никакого способа реализовать dynamic_cast без какой-либо информации о типе хранящейся в объекте для использования во время выполнения. И есть только две особенности языка, которым нужна информация о времени выполнения для типа объекта: виртуальные функции и dynamic_cast.

Если бы можно было использовать dynamic_cast на обратном приведение без полиморфных типов, законопослушные бы хранить информацию о типе времени выполнения в каждого типа класса. Это будет идти непосредственно против «платить только за то, что вы используете» Философия C++, и было бы совершенно разорвать его совместимость с C и многих внешних интерфейсов, аппаратных средств и т.д. Там не будет никаких типов классов стандартной компоновки, в основном. Или, альтернативно, нет типов классов, в которых вы могли бы полностью контролировать свой макет.

+0

Итак, объекты полиморфных типов хранят информацию об их реальном типе, более или менее? – user5539357

+0

@ user5539357 Да. Им нужно хранить такую ​​информацию в определенной форме или форме, чтобы иметь возможность выполнять динамическую диспетчерскую (виртуальные функции) правильно. – Angew

3

Предпосылка dynamic_cast является то, что он использует RTTI (предположительно каждая реализация использует ту же базовую структуру данных для поддержки dynamic_cast и RTTI - инфо типа должен где-то жить и различные представления для двух случаев использования не имеет смысла), чтобы сделать убедитесь, что бросок, который вы пытаетесь, соответствует правильному типу во время выполнения. Если из класса не является полиморфным, информация о типе не будет доступна компилятору для проверки типа (чтобы было принято решение вернуть 0 или преобразованный указатель).

+1

Разве это не деталь реализации? – user5539357

Смежные вопросы