2016-06-30 1 views
2

dire que je que j'ai ces classes:Existe-t-il un moyen d'utiliser dynamic_cast lors de la diffusion vers un enfant?

struct Parent {}; 
struct Child : public Parent { 
    void func() {} 
}; 

dire maintenant que je voulais créer une fonction comme ceci:

void foo(Parent* arg) { 
    auto child = dynamic_cast<Child*>(arg); 

    if(child != nullptr) child->func(); 
} 

Mais, évidemment, cela me donnera évidemment l'erreur:

dynamic_cast : Parent is not a polymorphic type

Donc, je ne peux pas faire l'étape dynamic_cast, est-il un moyen que je peux valider que arg est en fait un Child* à l'exécution?

Répondre

5

Non, vous ne pouvez pas. Les informations que vous pouvez obtenir sur un objet au moment de l'exécution sont obtenues en utilisant le RTTI (Run Time Type Information). Le RTTI d'un objet est stocké dans la table virtuelle de sa classe. Chaque objet d'une classe polymorphe (c'est-à-dire une classe qui a une ou plusieurs fonctions virtuelles, ou une classe dérivée d'une classe polymorphe) contient un vptr, qui est un pointeur vers la table virtuelle de la classe correspondante. Un objet de type non polymorphe n'a pas de vptr et il n'y a pas de table virtuelle pour sa classe. Par conséquent, vous ne pouvez pas utiliser dynamic_cast sur des types non polymorphes.

Ainsi, comme @lorro dit, vous devez ajouter une fonction virtuelle à Parent, et l'option la plus simple est l'ajout d'une destructor virtuelle (que vous devriez faire de toute façon):

struct Parent { 
    virtual ~Parent() {} 
}; 
8

Donnez à votre classe Parent une fonction virtuelle. Destructeur vient à l'esprit, pour plusieurs raisons (comme la suppression d'un enfant via la base ptr, etc.).