2016-05-12 1 views
3

J'essaie de convertir un objet de classe de base en objet de classe dérivé avec dynamic_cast, mais dynamic_cast renvoie null. Est-il possible de baisser en utilisant dynamic_cast?La rétrogradation à l'aide de dynamic_cast renvoie la valeur nulle

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

struct B : A {}; 


int main() 
{ 
    A* a = new A(); 

    B* b = dynamic_cast<B*>(a); 
    if(b){ 
     std::cout << "b has value" << std::endl; 
    }else{ 
     std::cout << "no value" << std::endl; 
    } 
} 

Ce code affiche "aucune valeur".

+0

FYI coulée * vers le bas * la chaîne d'héritage est appelée coulée vers le bas. – NathanOliver

+2

Vous ne pouvez pas obtenir un B à partir d'un A, que ferait le langage si, par ex. Les instances B comptaient plus de membres de données que d'instances A? –

+3

Vous ne pouvez pas baisser 'a' à' B * ', car il ne pointe pas sur un' B', il pointe sur un 'A':' A' n'est pas un 'B'. Vous pourriez cependant lancer un 'B *' à un 'A *' parce que le 'B *' pointerait sur un B, lequel "est un" A (définition de l'héritage) – KABoissonneault

Répondre

14

Parce que a pointe vers A en fait, pas un B, puis dynamic_cast échouera.

Est-il possible de baisser en utilisant dynamic_cast?

Oui, vous pouvez, par ex. si a points B exactement,

A* a = new B; 
B* b = dynamic_cast<B*>(a); 

Voir http://en.cppreference.com/w/cpp/language/dynamic_cast

5) Si l'expression est un pointeur ou une référence à une base de type polymorphes et new_type est un pointeur ou une référence au type dérivé d'un terme le temps de vérification est effectué:

a) L'objet le plus dérivé pointé/identifié par l'expression est examiné. Si, dans cet objet, l'expression pointe/se réfère à une base publique de Derived, et si un seul sous-objet de type Derived est dérivé du sous-objet pointé/identifié par expression, alors le résultat des cast/se réfère à ce sous-objet Derived. (Ceci est connu comme un "baissés".)

...

c) Dans le cas contraire, le contrôle d'exécution échoue. Si le dynamic_cast est utilisé sur des pointeurs, la valeur de pointeur NULL de type new_type est renvoyée. S'il était utilisé sur des références, l'exception std::bad_cast est levée.

+0

Puis-je utiliser 'dynamic_cast' si l'objet de base a supprimé ctor par défaut et peut être créé uniquement avec la fonction statique 'create'? – Herrgott

+0

@Herrgott Oui. 'dynamic_cast' fonctionne avec des pointeurs et des références, qui n'impliqueront pas les constructeurs par défaut de la classe de base. – songyuanyao

4

C'est par conception. dynamic_cast est utilisé lorsque vous voulez tester si un pointeur vers un objet de classe de base pointe vers une sous-classe ou non. S'il s'agit d'un objet de sous-classe, dynamic_cast vous donnera un pointeur valide, et si ce n'est pas le cas, vous obtiendrez simplement un nullptr.

Lorsque vous avez créé un objet de classe A et que A n'est pas une sous-classe de B, dynamic_cast renvoyait normalement un pointeur NULL.