2010-06-02 7 views
2

Ma question est liée à RTTI en C++ où j'essaie de vérifier si un objet appartient à la hiérarchie de type d'un autre objet. La méthode BelongsTo() vérifie cela. J'ai essayé d'utiliser typeid, mais cela génère une erreur et je ne suis pas sûr de la façon dont je peux trouver le type de cible à convertir lors de l'exécution.Type coulée en C++ en détectant le type d'objet 'this' actuel

#include <iostream> 
#include <typeinfo> 

class X 
{ 
    public: 
     // Checks if the input type belongs to the type heirarchy of input object type 
     bool BelongsTo(X* p_a) 
     { 
      // I'm trying to check if the current (this) type belongs to the same type 
      // hierarchy as the input type 
      return dynamic_cast<typeid(*p_a)*>(this) != NULL; // error C2059: syntax error 'typeid' 
     } 
}; 

class A : public X 
{ 
}; 

class B : public A 
{ 
}; 

class C : public A 
{ 
}; 

int main() 
{ 
    X* a = new A(); 
    X* b = new B(); 
    X* c = new C(); 
    bool test1 = b->BelongsTo(a); // should return true 
    bool test2 = b->BelongsTo(c); // should return false 
    bool test3 = c->BelongsTo(a); // should return true 
} 

Faire la méthode des classes virtuelles et de laisser faire dérivés, il semble être une mauvaise idée que j'ai beaucoup de classes dans la même hiérarchie de type. Ou est-ce que quelqu'un connaît un autre moyen de faire la même chose? Veuillez suggérer.

Mise à jour: b.BelongsTo (a) doit détecter si le type d'objet d'entrée (a) est un ancêtre de l'objet courant (b) dans la hiérarchie de types.

+0

Bien que je ne suis pas sûr que cela peut b Bien fait, je ne sais pas non plus comment cela * pourrait être utile. Juste par curiosité, pourquoi voulez-vous y parvenir? – ereOn

+0

S'il vous plaît voir les commentaires sur la réponse de Neil pour un exemple. – Elroy

+0

Par exemple. C dérive de B dérive de A, X dérive de A. Dans certains cas, je dois vérifier que le type d'objet que je reçois pointé par le pointeur de classe de base (A *) doit être de type B et non de type X, à défaut que je vais jeter une erreur. – Elroy

Répondre

2

Cela n'a aucun sens - le fait même que vous puissiez appeler la fonction signifie que le paramètre appartient à la hiérarchie X, car c'est le type du paramètre. Les distributions dynamiques ont pour but de trouver le type réel dans une hiérarchie connue.

L'erreur de syntaxe dans votre code:

return dynamic_cast<typeid(*p_a)*>(this) != NULL; 

est parce qu'un typeid est pas un type - vous ne pouvez pas l'utiliser comme un type avec dynamic_cast comme ça.

Si comme Naveen vous suggère voulez savoir si une instance appartient à une sous-hiérarchie, utilisez:

if (dynamic_cast <A*>(some_x_ptr)) { 

    // yes, belongs to A sub-hierarchy 
} 

Edit: Vous avez:

A <- P <- X 
A <- Q <- Y 

Puis:

A * a = new X; 

dynamic_cast <P *>(a); // not null 
dynamic_cast <Q *>(a); // null 
+0

Notez que la classe B et la classe C sont dérivées de la classe A. Je pense que l'intention de OP est de trouver si les objets passés appartiennent à cette sous-hiérarchie ou non. – Naveen

+0

Je m'excuse de ne pas me rendre vraiment clair ici. Par exemple. X dérive de P, Y dérive de Q, où P et Q dérivent de A. Donc, X appartient à P et A, Y appartient à Q et A mais X n'appartient pas à Q. J'ai besoin de ce comportement. – Elroy

+0

Je ne suis pas sûr s'il y a un nom pour ce genre de détection mais cela ressemble à vérifier les ancêtres. – Elroy

2

Pour que le RTTI fonctionne, class X a besoin d'au moins une fonction membre virtuelle (le destructeur virtuel compte aussi). Sans les fonctions des membres virtuels, la classe n'aura pas de vtable générée par le compilateur. Ainsi, lorsque vous appelez typeid, ce dernier ne fonctionnera pas comme prévu.

+0

J'ai ajouté un destructeur virtuel dans chaque classe. Mais il montre toujours cette erreur de syntaxe. Des idées? – Elroy

+0

Oui, voir la réponse de Neil Butterworth. – sharptooth