2009-12-31 7 views
5

Si je comprends bien, typeid peut déterminer le type réel dans le polymorphisme, alors que typeof ne peut pas.Obtention du type de variable

Est-il également vrai que leurs rendements sont utilisés à des fins différentes: le retour de typeof est utilisé comme mot-clé de type qui peut définir une variable, mais le retour de typeid ne peut pas?

Est-il possible d'obtenir le type actuel de polymorphisme et d'utiliser le mot-clé return en tant que type pour définir une autre variable? J'espère obtenir le type de classe dérivé d'un pointeur pointant vers la classe de base et définir une variable de ou un pointeur vers la classe dérivée. Quelque chose comme:

baseclass *p = new derivedclass 
typexxx(*p) *pp = dynamic_cast<typexxx(*p) *> (p); 
// would like to convert the pointer from pointing to a base class 
// to its derived class 

Merci beaucoup!

+6

Pouvez-vous donner un exemple de POURQUOI vous voulez faire cela? Le point principal d'une hiérarchie d'héritage est que vous n'avez normalement pas besoin de connaître le type réel. –

+0

Je veux juste faire référence à certains membres définis dans la classe dérivée mais pas dans la classe de base. Je ne suis pas sûr que ce soit une bonne idée d'ajouter des fonctions membres à la classe de base avec le même nom que celles de la classe dérivée et de les déclarer virtuelles, car ces fonctions membres sont trop spécifiques à cette classe dérivée les classes dérivées, et la fonction de base sera plus grande si je les ajoute. – Tim

+1

OK, vous pouvez faire ce que vous voulez avec dynamic_cast, mais vous devrez utiliser un if-ladder pour créer les pointeurs de type dérivés. –

Répondre

7

c++0x aura decltype qui peut être utilisé comme ceci:

int someInt; 
decltype(someInt) otherIntegerVariable = 5; 

mais bon vieux C++, malheureusement, non.

Je suppose que decltype ne sera pas vraiment beaucoup d'aide soit bien puisque vous voulez le type polymorphes, pas le type déclaré. La façon la plus directe de faire ce que vous voulez est de tenter de lancer un cast dynamique vers un type particulier et de vérifier NULL.

struct A { 
    virtual ~A() {} 
}; 
struct B : public A {}; 
struct C : public A {}; 

int main() { 
    A* x = new C; 
    if(B* b_ptr = dynamic_cast<B*>(x)) { 
     // it's a B 
    } else if(C* c_ptr = dynamic_cast<C*>(x)) { 
     // it's a C 
    } 
} 
+0

Merci Evan! Mais parfois, j'ai besoin de déterminer le type à l'exécution, par exemple via l'argument de la ligne de commande. Voir mon post ici http://stackoverflow.com/questions/1984492/runtime-determine-type-for-c, vous comprendrez. – Tim

+0

'si (B * b_ptr = dynamic_cast (x))' et pas besoin de l'union ou des variables mis-scoped. De plus, vous pouvez écrire plus naturel 'else if' au lieu de' else {... if ...} ' –

+0

@Roger: vous apprenez quelque chose de nouveau tous les jours, je ne savais pas que vous pouviez déclarer une variable dans une instruction if. et aboutir à une portée appropriée. Je vais mettre à jour ma réponse. –

3

En supposant une hiérarchie A < - B < - C

A * p = new AorBorC; // create new object of some sort 

if (dynamic_cast <C*>(p)) { 
    C * c = dynamic_cast <C*>(p); 
    c->CFunc(); 
} 
else if (dynamic_cast <B*>(p)) { 
    B * b = dynamic_cast <B*>(p); 
    b->BFunc(); 
} 
else if (dynamic_cast <A*>(p)) { 
    A * a = dynamic_cast <A*>(p); 
    a->AFunc(); 
} 

Où AFunc, BFunc, cfunc sont spécifiques à leurs classes respectives, et non virtuelle. Évidemment, cela peut être optimisé quelque peu.

+0

'if (C * c = dynamic_cast (p)) {/ * utilise c * /}' Pas besoin de lancer deux fois. –

+1

Tout à fait - J'essayais de rendre les choses plus claires en étant long. –

Questions connexes