downcasting dynamic_cast с неполиморфными классами, почему он не компилируется?

У меня есть следующий код:

using namespace std;

class BaseOk
{
public:
virtual void ImplementMe()
{
};
};
class DerivedOk : public BaseOk
{
public:
void ImplementMe()
{
}
};

class CBase { };
class CDerived: public CBase { };int main()
{
CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived  -> this doesn't compile

// Polymorphic case

BaseOk b2; BaseOk* pb2;
DerivedOk d2; DerivedOk* pd2;

pb2 = dynamic_cast<BaseOk*>(&d2);     // ok: derived-to-base
pd2 = dynamic_cast<DerivedOk*>(&b2);  // wrong: base-to-derived -> this returns a NULL pointer

}

Строка с указателем «pd» выполняет downcast, и я согласен с тем, что она должна завершиться неудачей, потому что результатом является совершенно другой объект.
Мой вопрос: почему dynamic_cast в этой строке не компилируется вообще, а просто возвращает нулевой указатель?

Я использую компилятор MSVC2012

2

Решение

Почему не dynamic_cast в этой строке компилировать вообще вместо
просто возвращает нулевой указатель?

Рассматривайте это как особенность / возможность, а не как ограничение.

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

Есть еще одно скрытое преимущество этого. Предположим, вы используете dynamic_cast со ссылками, если это не удается, то генерируется исключение. Кто-нибудь захочет обработать исключение для чего-то, что уже известно во время компиляции!

2

Другие решения

С помощью dynamic_cast указатель на неполиморфный тип является ошибкой. Это диагностируемое правило, поэтому вы должны получить ошибку во время компиляции.

Использование его для указателя на полиморфный тип, который не может быть преобразован в целевой тип, не является ошибкой и, в любом случае, обычно не обнаруживается при компиляции. Он имеет четко определенное поведение, давая нулевой указатель.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector