web-dev-qa-db-fra.com

Vérification de type en C ++

En C++, je veux savoir si le type réel de l'objet est de la même classe, pas de la même classe ou dérivée. Ceci est similaire au code C # suivant:

Class Base
{
}

Class Child:Base
{
}

Base childObject = new Child();

If (childObject.GetType() == typeof(Child))
{
 // do some code
}

Merci!

30
Homam

Vous pouvez procéder de deux manières. Tout d'abord, vous pouvez utiliser l'opérateur typeid, qui renvoie une structure type_info Contenant des informations sur le type de l'objet. Par exemple:

Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
    /* ... ptr points to a DerivedType ... */
}

Notez que vous devez utiliser typeid(*ptr) et non typeid(ptr) ici. Si vous utilisez typeid(ptr), vous récupérerez alors un objet type_info Pour Base*, Car le pointeur a le type Base* Quel que soit son pointage .

Un point important à noter est que cela vérifiera si ce que ptr pointe est exactement comme DerivedType. Si ptr pointe sur un objet d'un type dérivé de DerivedType (peut-être un EvenMoreDerivedType), ce code ne fonctionnera pas correctement.

Une autre façon de vérifier si vous pointez sur un objet d'un type un peu plus robuste consiste à utiliser l'opérateur dynamic_cast. dynamic_cast Effectue un transtypage vérifié lors de l'exécution qui donnera un pointeur valide si le transtypage réussit et NULL sinon. Par exemple:

Base* ptr = /* ... */;
DerivedType* derived = dynamic_cast<DerivedType*>(ptr);
if (derived) {
    /* ... points to a DerivedType ... */
}

Cela a l'avantage supplémentaire que si ptr pointe vers quelque chose comme un EvenMoreDerivedType, le cast réussira quand même parce que EvenMoreDerivedType hérite de DerivedType.

Enfin, vous voyez parfois du code comme celui-ci:

Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
     /* ... points to a DerivedType ... */
}

Cela étend localement le pointeur derived au corps de l'instruction if et utilise le fait que les valeurs non nulles sont évaluées à true en C++. Personnellement, je trouve cela plus facile à lire et moins sujet aux erreurs, mais allez certainement avec ce qui est le plus facile pour vous.

J'espère que cela t'aides!

56
templatetypedef

Bien que la réponse de DeadMG soit correcte (j'ai utilisé plusieurs fois typeid), je pensais que je lancerais cela pour la postérité. La "bonne" façon de procéder, à partir d'une vue orientée objet, est la suivante:

Class Base
{
    virtual void something() {
        // probably a no-op, but maybe some default stuff
    }
}

Class Child : public Base
{
    virtual void something() {
        // do your child-specific code here
    }
}

Base* childObject = new Child();
childObject->something();  // does the right thing
11
Tim

Vous pouvez utiliser typeid ().

if (typeid(childObject) == typeid(ChildType)) {
}

Si cela retourne vrai, alors vous savez que c'est la classe enfant.

2
Puppy