Comment puis-je vérifier si un objet est une sous-classe donnée en C++?
Je pensais le long des lignes de l'aide typeid()
mais je ne sais pas comment faire pour demander si ce type est une sous-classe d'une autre classe (qui, au passage, est abstraite)
Vous devez vous connecter pour publier un commentaire.
Vous ne devriez vraiment pas. Si votre programme doit connaître la classe d'un objet, qui indique généralement un défaut de conception. Voir si vous pouvez obtenir le comportement que vous souhaitez à l'aide de fonctions virtuelles. Aussi, plus d'informations sur ce que vous essayez d'aider.
Je suis en supposant que vous avez une situation comme celle-ci:
Si c'est ce que vous avez, alors essayez de faire quelque chose comme ceci:
Edit: Depuis le débat à propos de cette réponse se poursuit encore après tant d'années, j'ai pensé que je devrais jeter un peu de références. Si vous avez un pointeur ou une référence à une classe de base, et que votre code doit connaître la classe dérivée de l'objet, alors elle viole Principe de substitution de Liskov. Oncle Bob appelle cela un "de l'anathème à la Conception Orientée Objet".
dynamic_cast<>
ici? N'est-ce passtatic_cast<>
être assez?x
au moment de la compilation? Si oui, alorsstatic_cast<>()
serait de travailler. Si vous ne pouvez pas dire le type dex
jusqu'à l'exécution, alors vous devezdynamic_cast<>()
Vous pouvez le faire avec
dynamic_cast
(au moins pour les types polymorphes).En fait, à bien y penser, on ne peut dire si c'est SPÉCIFIQUEMENT un type particulier avec
dynamic_cast
--mais vous pouvez dire si c'est ce type ou d'une sous-classe de celle-ci.dynamic_cast
pouvez déterminer si le type contient le type de cible n'importe où dans la hiérarchie d'héritage (oui, c'est une fonctionnalité peu connue que siB
hérite deA
etC
, il peut tourner unA*
directement dans unC*
).typeid()
pouvez déterminer le type exact de l'objet. Toutefois, ceux-ci devraient à la fois être utilisé très rarement. Comme il a été déjà mentionné, vous devriez toujours être en évitant de type dynamique d'identification, car il indique un défaut de conception. (aussi, si vous savez que l'objet est à coup sûr du type de cible, vous pouvez faire un abattu avec unestatic_cast
. Boost offre unpolymorphic_downcast
, qui sera abattu avecdynamic_cast
etassert
en mode debug, et en mode release, il suffit d'utiliser unstatic_cast
).Je suis en désaccord que vous ne devriez jamais vous voulez vérifier le type de l'objet en C++. Si vous pouvez l'éviter, je suis d'accord que vous devriez. Dire que vous ne devriez JAMAIS faire cela en toute circonstance est aller trop loin cependant. Vous pouvez le faire dans un grand nombre de langues, et il peut rendre votre vie beaucoup plus facile. Howard Pinsley, par exemple, nous a montré comment, dans son post sur le C#.
Je fais beaucoup de travail avec le Framework Qt. En général, j'ai le modèle de ce que je fais après la manière de faire les choses (au moins quand travail dans leur cadre). La classe QObject est la classe de base de tous les objets Qt. Cette classe a pour fonctions isWidgetType() et isWindowType() comme sous-classe de la vérifier. Alors pourquoi ne pas être en mesure de vérifier vos propres classes dérivées, ce qui est comparable dans la nature? Voici un QObject spin-off de certains de ces autres postes:
Et puis, quand vous êtes de passage autour d'un pointeur vers un QObject, vous pouvez vérifier si il des points à votre classe dérivée par l'appel de la fonction membre statique:
Je ne sais pas si j'ai bien compris votre problème correctement, alors permettez-moi de reformuler dans mes propres mots...
Problème: étant Donné classes
B
etD
, de déterminer siD
est une sous-classe deB
(ou vice-versa?)Solution: Utilisation de certains modèles de la magie! Bon, sérieusement vous avez besoin de prendre un coup d'oeil à LOKI, un excellent modèle de méta-programmation de la bibliothèque produit par le légendaire C++ auteur Andrei Alexandrescu.
Plus précisément, télécharger LOKI et inclure l'en-tête
TypeManip.h
dans votre code source puis utilisez leSuperSubclass
modèle de classe comme suit:Selon la documentation,
SuperSubClass<B,D>::value
sera vrai siB
est une base publique deD
, ou siB
etD
sont des alias du même type.c'est à dire soit
D
est une sous-classe deB
ouD
est le même queB
.J'espère que cette aide.
edit:
Veuillez noter que l'évaluation de
SuperSubClass<B,D>::value
qui se passe au moment de la compilation contrairement à certaines méthodes qui utilisentdynamic_cast
, donc il n'y a pas de pénalité pour l'utilisation de ce système lors de l'exécution.Résultat:
Vous ne pouvez le faire qu'au moment de la compilation à l'aide de modèles, sauf si vous utilisez RTTI.
Elle permet d'utiliser le typeid fonction qui donnera un pointeur vers un type_info structure qui contient des informations sur le type.
Lire à Wikipédia
En c# vous pouvez simplement dire:
Bien, oui, ça pourrait être fait en comparant:
typeid().name()
. Si nous prenons les déjà décrit la situation où:Une possible mise en œuvre de
foo(Base *p)
serait:Le code ci-dessous montre 3 différentes façons de le faire:
Le programme ci-dessus affiche le: