Dans le contrôle C de si deux instances d'une classe de base sont enfait de la même sous-classe

StackOverflow https://stackoverflow.com/questions/3863567

  •  27-09-2019
  •  | 
  •  

Question

Le code ci-dessous explique le problème. Remplissez same_sub_class pour détecter si les deux pointeurs vers la classe de base virtuelle A sont en fait le même béton classe.

struct A {
    ...
}:

struct B : public A {
    ...
}:

struct C : public A {
    ...
}


bool same_sub_class(A * a1, A * a2){
    // Fill this in to return true if a1 and a2 are
    // of the same concrete class
}

EDIT:

Quand je regarde ma demande je besoin de quelque chose un peu différent de ce qui précède. Je dois pouvoir aux instances de groupe par leur type_id.

Pour votre information. J'ai un mini-système de algerbra symbolique afin de faire des manipulations, il est important de connaître le type de classe parfois pour le tri, et les expressions réarranger.

Donc, étant donné un vecteur de pointeurs par exemple comment les regrouper par leur type_id. J'avais soit besoin d'être en mesure de hachage du type_id ou de générer un entier unique pour chaque classe.

Était-ce utile?

La solution

Si vous pouvez utiliser RTTI,

typeid(*a1) == typeid(*a2)

Je pense que vous devez également

#include <typeinfo>

Et vous devez avoir une fonction virtuelle dans vos classes afin que le vtable existe -. Un destructor devrait faire amende

UPDATE :

Je ne suis pas sûr que je comprends parfaitement ce que vos besoins sont pour le regroupement, mais vous pouvez essayer d'utiliser le valeur de retour de l'opérateur de typeid soit:

  • Hash la chaîne retournée de typeid(*ptr).name()
  • Utilisez typeid(*a1).before(typeid(*a2)) comme critère de commande. Cela n'a pas de déterminisme entre les courses, cependant.

En général, lorsque l'on considère RTTI, il est une bonne idée de voir si cela peut être accompli en utilisant mieux les fonctions virtuelles bien conçu ( à double expédition, par exemple). Je ne peux pas dire s'il y a une bonne alternative dans votre cas si, puisque je ne comprends pas les détails.

Autres conseils

typeid(*a1) == typeid(*a2)

Notez le déréférencement, il est important.

Vous pouvez faire votre propre identificateur de type:

struct A{
...
protected:
 enum TypeTag{B_TYPE, C_TYPE};
 TypeTag typeTag;
};

Et puis dans les constructeurs de sous-classes:

B::B()
: typeTag(TypeTag::B_TYPE)
{
...
}

C::C()
: typeTag(TypeTag::C_TYPE)
{
...
}

Il existe une fonction en C ++ appelé RTTI (informations de type d'exécution) qui vous permet de faire de telles choses.

Une autre possibilité d'avoir le contrôle de type d'exécution est de créer une classe de base à partir de laquelle toutes vos classes dérivent. Dans votre classe de base comprend un champ qui contient son type comme une chaîne ou un nombre.

En fait, il y a une réponse assez simple à cela. Mais il consiste à poser des questions un peu plus clair.

(A) Si je veux stocker typeinfo objets dans un unordered_set que dois-je faire?

typeinfo soutenir le == et la méthode de nom (). Le nom peut être utilisé pour générer un hachage et == pour l'égalité

(B) Si je veux stocker typeinfo objets dans un ordered_set (std :: set) que dois-je faire?

typeinfo supporte le == et le procédé avant (). Avec peu d'emballage de ces deux méthodes que je peux implémenter une interface pour une fonction de comparaison qui me donne la commande stricte faible.

Une astuce qui peut ou peut ne pas fonctionner avec RTTI, selon votre compilateur, est le suivant:

const type_info &a1_type_info= typeid(*a1);
const type_info &a2_type_info= typeid(*a2);

return &a1_type_info==&a2_type_info || a1_type_info==a2_type_info;

Si votre compilateur crée des instances type_info par la valeur, cela ne fonctionne pas le premier test, mais réussir sur le second test. Si votre compilateur met en cache les instances, le premier test à réussir (si elle est du même type) et être beaucoup plus rapide car il est juste un pointeur comparer. Si votre compilateur renvoie les différentes instances parce a1 et a2 sont venus de différentes bibliothèques partagées, il devrait fonctionner.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top