7
votes

Pointeur de coulée du type de base au type enfant

Je construis un simple design de jeu pour un projet de mien. J'ai les classes suivantes: xxx pré>

et ensuite j'ai un tas de classes qui dérivent de caractère ou de non-jouisseur. Je le définis comme si: p> xxx pré>

Mon problème est que, à un moment donné, je voudrais effectuer une certaine opération sur l'un des éléments du vecteur. Donc, obtenir un élément hors du vecteur que je ne peux pas appeler directement la méthode getnpcstate () code> car l'élément du vecteur est de caractère * Type. Ce faisant cela: p>

NonPlayableCharacter* test = dynamic_cast<NonPlayableCharacter*>(_allChar[0]);
test->GetNPCState();


2 commentaires

Vous obtenez un pointeur NULL lorsque l'objet que vous essayez de lancer vers nonplayableCharacter n'est-il pas un nonplayablecharacter . Probablement certains des objets du vecteur sont directement dérivés du caractère .


De côté, je travaille avec un composant (s) qui utilise de nombreux vecteurs de pointeurs. Cela a causé beaucoup de problèmes pour moi, car ce vecteur se termine parfois avec des pointeurs sur la mémoire supprimée, et cela conduit à la corruption de la mémoire. Je suppose que vous utilisez un vecteur de pointeur parce que vous l'utilisez polymorphiquement, et / ou les objets sont partagés. Dans les deux cas, je recommande vivement de changer votre vecteur pour détenir un type de pointeur partagé ( std :: partagé_ptr par exemple) ou changez votre vecteur sur boost :: ptr_vector (qui est idéal pour les deux scénarios). Bonne chance avec le jeu!


7 Réponses :


3
votes

dynamic_cast renvoie null si la distribution est impossible. Vérifiez ce qui est à l'intérieur _allchar [0] . Vous pouvez créer une fonction comme gettype () où renvoie l'identifiant de type prédéfini d'objet, puis utilisez static_cast : xxx


0 commentaires

5
votes

après xxx

Vous devez vérifier si test est null . Même si _AllChar [0] n'est pas NULL, le dynamic_cast peut retourner null si l'objet qu'il pointe de ne pas être un NonplayableCharacter .

La version correcte serait la suivante: xxx


0 commentaires

2
votes

Vous devez tester le dynamic_cast code> pour le succès. Il renvoie un pointeur NULL lors de l'échec suivant:

NonPlayableCharacter* test = dynamic_cast<NonPlayableCharacter*>(_allChar[0]);
if (test) test->GetNCPState();


0 commentaires

2
votes

dynamic_cast renvoie null lorsque son argument ne pointe pas sur un nonplayablecharacter (donc le premier élément de la matrice pointe probablement sur une autre Sous-classe du caractère ) - Vous devez donc vérifier null après la distribution. Cependant, en utilisant dynamic_cast peut indiquer un problème de conception. Peut-être devriez-vous plutôt avoir une méthode virtuelle sur caractère appelé par ex. EffectuerMainAgentingAmeloop () et est remplacé de manière appropriée dans les différentes sous-classes?


0 commentaires

2
votes

Pour obtenir un pointeur enfant d'un pointeur de base que vous devez utiliser dynamic_cast . Son comportement est le suivant:

  • Si le pointeur pointe vers un enfant * alloué avec nouvel enfant alors dynamic_cast retourne un enfant * < / code>
  • Si le pointeur pointe vers quelque chose d'autre, alors dynamic_cast renvoie null .

    Votre problème est que vous n'avez pas été alloué avec nouveau ou votre objet est d'un type différent.


0 commentaires

2
votes

Il y a probablement une meilleure solution oo à utiliser dynamic_cast, mais tout le point d'utilisation de cette distribution est qu'il retournera un pointeur null si le moule échoue.

Vérifiez pour NULL avant d'appeler getnpcstate (); < / p> xxx


0 commentaires

6
votes

Il existe plusieurs types de moulages en C ++ (4), dont 2 sont des intérêts ici:

  • static_cast suppose que vous savez ce que vous faites
  • dynamic_cast chèques, au moment de l'exécution que vous "devinez" droit

    Remarque: simplifié, comme dynamic_cast permet également des coulées croisées et des moulages impliquant des bases virtuelles.

    Il y a 3 versions de dynamic_cast , en fonction de la nature de la cible:

    • Si la cible est une référence (c'est-à-dire dynamic_cast (u) ), alors si la vérification échoue dynamic_cast jette un std :: bad_cast < / Code> Exception
    • Si la cible est un pointeur (c.-à-d. dynamic_cast (p) ), si les chèques échouent dynamic_cast renvoie un pointeur null
    • Enfin, en tant que cas particulier, si la cible est vide * , alors dynamic_cast renvoie plutôt l'adresse de l'objet complet

      Dans ce cas, vous pouvez:

      • Switch à partir de dynamic_cast (_ allchart [0]) -> getnpcstate () à dynamic_cast (* _ _ allchart [0]). Getnpcstate () et laisser l'exception propage
      • Testez le résultat de la distribution ( non jouetable * Test ICI) pour la non-nullité

0 commentaires