c++ casting de la classe de base de la classe dérivée de mess
Si je devais créer une classe de base appelée base
et les classes dérivées appelé derived_1
, derived_2
etc... j'utilise une collection d'instances de la classe de base, puis quand j'ai récupéré un élément et a essayé de l'utiliser, je trouve que le C++ pense que c'est le type est celui de la classe de base, probablement parce que j'ai récupérée à partir d'un std::vector
de base. Qui est un problème quand je veux utiliser des fonctionnalités qui n'existent que pour la classe dérivée qui est du type que je savais que cet objet a été quand je l'ai mis dans le vecteur.
Donc je jette l'élément dans le type dont il est censé être et trouvé ceci ne fonctionnerait pas.
(derived_3)obj_to_be_fixed;
Et de rappeler que c'est un pointeur chose. Après quelques ajustements cela fonctionne aujourd'hui.
*((derived_3*)&obj_to_be_fixed);
Est-ce vrai ou est-il par exemple un abc_cast()
fonction qui le fait avec moins de désordre?
edit:
J'ai dû l'étendre vers une autre question, le plein de solutions sont indiqués. stackoverflow.com ... pourquoi-le-polymorphe-types de l'erreur-et-nettoyage-question
std::vector< base >
ou un std::vector< base * >
? Parce que dans le premier cas, si vous êtes de stocker des objets de la classe dérivée, il ya probablement aussi un objet de découpage se passe...Ouch. En général, vous ne devriez pas faire cela parce que, comme déjà dit, vous aurez objet de découpage (en.wikipedia.org/wiki/Object_slicing), qui permet en fait de réduire tous vos objets instances de la classe de base; si vous voulez stocker des objets de différentes classes dérivées de la même hiérarchie de classe, vous devez utiliser un
std::vector< base *>
; cela permet de garder les objets intacts, bien que vous aurez toujours comme des pointeurs vers la classe de base (voir @Peon la Grande la réponse de voir la façon de traiter avec eux).Merci pour l'objet de découpage info, de telles choses pas claires en C++. Je vais changer ma carte pour contenir des pointeurs de la place.
(derived_3&)obj_to_be_fixed
peuvent apparaître à travailler, mais il n'a pas!Eu Oli. Merci. Je vais utiliser les std::vector<*> solution maintenant.
OriginalL'auteur alan2here | 2011-01-08
Vous devez vous connecter pour publier un commentaire.
Si vous stockez vos objets dans un
std::vector<base>
il n'y a simplement aucun moyen de revenir à la classe dérivée. C'est parce que la dérivée de la partie a été coupée de rangement dans une instance de la classe de base (après tout vecteur contient des copies de vos données, de sorte qu'il joyeusement exemplaires seulement la partie basse de votre objectes), faisant l'objet stocké une véritable instance de la classe de base, au lieu d'une classe dérivée utilisée comme classe de base.Si vous souhaitez stocker des objets polymorphes dans le vecteur d'en faire un
std::vector<base*>
(ou une sorte de smartpointer à la base, mais pas de la base elle-même) et l'utilisationdynamic_cast<derived_3*>
de le jeter vers le bon type (oustatic_cast
, si ses performances sensibles et vous êtes assez confiant que vous êtes en train de jeter le type correct (dans ce cas, des choses horribles qui va vous arriver si vous avez tort, alors méfiez-vous)).OriginalL'auteur
Si vous utilisez un
vector
debase
alors tous à vos instances sontbase
instances et ne provenant pas de cas.Si vous essayez d'insérer un dérivé de l'instance, l'objet sera tranches de. L'insertion dans une
vector
implique toujours un copie et le type de cible est déterminé par le type de l'objet que le vecteur détient. Unvector
ne peut pas tenir des objets de types différents.peut contenir un mélange de types". Ce n'est tout simplement pas vrai, j'en ai peur. Si vous utilisez
std::vector< base* >
vous avez un vecteur de pointeurs. Les pointeurs peuvent pointer vers des objets de différents types, mais les pointeurs eux-mêmes sont tous du même type. Et maintenant, parce que ton vecteur est un vecteur de pointeurs, vous savez gérer les objets que ceux pointer à sont stockées puisque les objets ne sont pas stockées dans le vecteur.Merci. Je missworded. Je ne savais pas en interne ce qui se passait ici. Bon point sur maintenant d'avoir à manege plus de choses.
C'est pourquoi nous avons boost::ptr_vector<base> qui va gérer le ptr objets pour vous.
OriginalL'auteur
La plupart du temps, vous ne devez pas faire cela. Soigneusement conçu hiérarchie de classe peut gérer cela par le polymorphisme (c'est à dire des fonctions virtuelles).
Si vous avez vraiment besoin de cast vers le type dérivé, l'utilisation
dynamic_cast
opérateur.Je suppose pointeurs sont utilisés dans le vecteur quand je vois cette question. OMI lancer des instances de l'objet dans le vecteur est une mauvaise conception. La bibliothèque Standard allocateurs de garantie seulement et ont été testé uniquement avec les primitives et les Standards de la bibliothèque de types. Autre chose que ces, les pointeurs sont de meilleurs choix.
Eh bien, le point de la question est que les pointeurs sont des pas utilisé dans le vecteur. 😉 et aussi whu? Les conteneurs de la bibliothèque Standard sont conçu pour stocker des valeurs, pas des pointeurs. Souvent, le stockage les pointeurs dans un conteneur est un mauvais design.
OriginalL'auteur
Ce que vous essayez de faire est de ne pas même à distance possible. Si les objets stockés dans le conteneur de type
base
, alors qu'ils sontbase
, période. Ils ne sont pasderived
des objets, ils ne deviendront jamais desderived
objets et ils ne peuvent pas être utilisés commederived
les objets indépendamment de ce que vous faites.Votre exprimés par le biais de pointeurs est rien que de juste un hack qui revisite la mémoire occupée par
base
objet commederived
objet. C'est totalement dépourvue de sens et ne peut "travailler" par accident.OriginalL'auteur