2013-03-14 4 views
2

У меня есть следующий код: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 

} 

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

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

+0

Сообщение об ошибке, которое вы получаете также –

+0

dynamic_cat принимает информацию RTTI, и если у вас нет полиморфных типов, у вас нет RTTI (попробуйте dynamic_cast int to float, вы столкнетесь с тем же) –

+0

Он компилируется для меня на gcc 4,7. – mfontanini

ответ

2

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

Рассмотрите это как функцию/объект, а не ограничение.

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

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

2

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

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

+0

'Использование dynamic_cast для указателя на не- -полиморфный тип является ошибкой' ... Я думаю, что «ошибка» является неправильным словом в этом контексте. Это довольно тривиально известная информация, которая «всегда ложна»; который сообщается пользователю с ошибкой компиляции. – iammilind

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

  • Нет связанных вопросов^_^