0
votes

Comment puis-je obtenir le type de variable un pointeur pointeur?

Je travaille sur certains déchirements 3D à l'aide de OpenGL et j'ai fait une classe de base objet , qui doit être utilisée pour tout type d'objet pouvant être rendu. Je stocke tous mes objets dans un vecteur de points d'objet.

Étant donné que différents objets peuvent nécessiter différents traitements par certaines fonctions, il serait pratique de savoir si un pointeur pointe sur un exemple de cube ou d'une sphère.

Voilà donc une manière en C ++ pour obtenir le type d'une variable lorsqu'un pointeur sur cette variable est connu?


12 commentaires

Dépend. Pouvez-vous donner un exemple plus concret de ce que vous voulez faire?


@Nathanoliver j'ai fait


La solution commune au problème que vous avez décrite est d'utiliser le polymorphisme à l'aide de fonctions de membre virtuel. Alors vous pouvez faire objet_vector [quelque_index] -> Virtual_function_name () et virtual_function_name appellera la version de la classe dérivée de la fonction de la fonction au lieu de la classe de base tant qu'elle est marquée virtuel dans la classe de base.


Si votre hiérarchie de type est de votre propre fabrication, cela vous ressemble, vous avez juste besoin de quelques méthodes polymorphes pour faire les actions dont vous avez besoin pour personnaliser ....? Vous pouvez implémenter des méthodes par défaut dans la classe de base de votre hiérarchie et les remplacer polymorphiquement dans les classes dérivées qui nécessitent un comportement spécial.


@Nathanoliver non, je ne veux pas dire ça. Je veux dire si une fonction externe passe sur mon vecteur d'objets et fait quelque chose à cela, alors je veux faire quelque chose de différent pour un type différent.


Oui ... Nathanoliver est parfaitement correct. Vous décrivez un cas parfait où vous avez juste besoin de polymorphisme.


@ user11914177 Vous stockez des pointeurs sur des objets dérivés dans le vecteur, non?


@Nathanoliver je stocke mes objets dérivés dans un vecteur de pointeurs de classe de base


Lorsque votre "fonction externe" est en boucle sur le vecteur de ces objets, il appelle simplement une méthode polymorphe pour faire tout ce qui est nécessaire (ou faire une décision de retour en vrais / faux), et pour la plupart des cas, la mise en œuvre par défaut fonctionne bien. Dans les seules classes spéciales nécessitant un comportement alternatif, vous remplacez cette méthode et cela fait quelque chose de différent dans les classes seulement.


Ces pointeurs de classe de base ... sont-ils d'un type que vous avez créé? Votre message dit "J'ai fait une classe de base objet ..." Alors je suppose que vous avez créé la classe de base.


Droite. Parce que vous avez un pointeur sur la classe de base, toute analyse de type statique ne vous donnera que la classe de base comme tapez le pointeur pointe sur quoi de quoi cela pointe réellement. Vous avez besoin de polymorphisme ou d'une autre technique comme celle-là, comme à l'aide d'un variante / tout et à l'aide du motif de visiteur.


Utilisation du polymorphisme, lorsque vous appelez une méthode polymorphe via ce pointeur, vous obtenez l'instance de classe dérivée de cette méthode, ce qui semble être exactement ce dont vous avez besoin. La boucle de code sur le vecteur n'a même pas besoin de savoir quel est le type de chaque élément; Cela appelle simplement la méthode polymorphe.


4 Réponses :


0
votes

Longue histoire courte: non.

Si vous possédez un pointeur tapé (E.G. Char * ) - Eh bien, cela pourrait être un char quel point le pointeur pointe, mais nous ne saurons jamais la vérité. Si vous possédez un «code> Void * Pointeur, alors bonne chance, vous n'allez rien trouver intéressant.

Les types n'existent pas au moment de l'exécution. La taille est préservée (int = 4 octets, double = 8 octets), mais aucune information de type n'est généralement garantie pour être stockée.


6 commentaires

J'aimerais savoir comment vous pouvez diviner la taille de l'objet à laquelle un void * points sans déjà connaître son type.


Vous ne pouvez pas. La taille est préservée pour les variables. Le pointeur est une variable et vous pouvez déduire la taille de Void * par arcan magie appelée Tailleof .


Vous dites "la taille est préservée (int = 4 octets, double = 8 octets), mais aucune information de type n'est généralement garantie". Donc, je demande comment vous pouvez obtenir ces informations de taille préservées sur un objet au moment de l'exécution sans connaître son type, donné uniquement un Void * à celui-ci. Je connais déjà la réponse, et ce n'est pas taille de (vide *) . Je vérifie juste pour voir si vous connaissez la réponse.


Vous avez mal compris ma réponse. La taille est conservée par exemple pour les variables, car le code en fait réellement référence tout en lisant ou en écrivant la pile. Aucune donnée de type n'est connue au moment de l'exécution. Je n'ai pas dit que je savais comment vérifier la taille d'un objet au moment de l'exécution tout en ayant un pointeur vide.


Si vous possédez un point vide * Pointeur, alors bonne chance, vous n'allez rien trouver intéressant. <- Voilà, une réponse dans une réponse.


Eh bien, si vous avez une variable elle-même (pas un vide * à celui-ci), vous êtes correct que vous pouvez obtenir la taille de celle-ci par Tailleof (Yourvariable) , Mais cela est résolu à la compilation, pas d'exécution. Et si vous avez un vecteur de pointeurs de classe de base à des implémentations dérivées de tailles différentes, tailleof (* vectofbaseclasspointers [n]) vous donnera la taille d'un objet de classe de base (s'il est instanciable), pas La taille de l'objet réel pointé vers par vectofbaseclasspoints [n] . Vous ne pouvez pas obtenir la taille d'un objet de classe dérivé au moment de l'exécution si vous n'avez pas de moyen de déterminer son type instancié réel.



0
votes

Il semble donc qu'il n'y ait pas de solution réelle à cette autre que d'utiliser des fonctions virtuelles.


1 commentaires

Pas exactement la solution SOLUTION ... mais je pense que les fonctions virtuelles sont la solution meilleure donnée à ce que vous avez décrit. Vous pouvez également stocker une valeur énumérée en tant que variable de membre (définie dans la classe de base) afin de pouvoir effectuer un commutateur (m_objecttypecode) sur celui-ci dans votre boucle ou utilisez RTTI ( type_info et typeid () ) pour le faire légèrement plus élégamment. Ou peut-être utiliser le schéma de visiteur comme le suggère de Lars. Toutes ces solutions seraient effectivement plus compliquées que de simplement utiliser des méthodes virtuelles.



1
votes

La meilleure solution à votre cas d'utilisation semble être le modèle de visiteur.

Explication de modèle de visiteur

https://fr.wikipedia.org/wiki/visitor_pattern

Le modèle vous permet d'implémenter un comportement spécifique à un type sans modifier la mise en œuvre de ces types (sauf l'étendre une fois bien sûr).


0 commentaires

0
votes

Option 1, coulé dynamique.

class ObjectCollection 
{
  virtual void drawAll();
  virtual void updateAll();
};
class BoxCollection : public ObjectCollection {};
class SphereCollection : public ObjectCollection {};

std::vector<ObjectCollection*> thingsInMyGame;


0 commentaires