Je travaille sur une application graphique qui utilise des classes virtuelles assez largement. Il a:
Une classe d'images, qui est essentiellement une collection de formes. p> li>
une classe de formes, purement virtuelle et a quelques classes qui héritent de celle-ci: p>
une forme de figure, qui est une figure graphique (également virtuelle), la forme hérite de celle-ci. p> li> ul>
Essentiellement, mon problème se résume à la mise en œuvre de la classe d'images, qui est essentiellement utilisé pour stocker une collection de formes. J'utilise actuellement un vecteur pour stocker des formes, mais il est évident qu'il s'agissait de la mauvaise décision depuis l'instanciation vectorielle de ces formes, ce qui n'est pas bon car ils sont purement virtuels. P>
ci-dessous est ma base de code actuelle (résumé un bit): p> Les messages d'erreur que je reçoivent sont juste un tas de ceux-ci: P> image.cpp: 33: instancié de
ici
/opt/local/bin/../lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/ext/new_allocator. H: 105:
Erreur: impossible d'attribuer un objet de
type abstrait 'forme' forme.h: 12:
Remarque: parce que le virtuel suivant
Les fonctions sont pure dans la "forme":
forme.h: 58: Remarque: vide virtuel
Forme :: get (std :: istream &) forme.h: 31:
Remarque: vide virtuel
Forme :: Met (STD :: Ostream &) Const
forme.h: 36: Note: Vide virtuel
Forme :: Échelle (Const Point &, Double)
forme.h: 40: Remarque: vide virtuel
Forme :: Traduire (Double, Double)
forme.h: 45: Note: Vide virtuel
Forme :: Reflechorizontalement (Double)
forme.h: 49: Remarque: vide virtuel
Forme :: réfléchissante (double)
forme.h: 52: Remarque: virtuel
Shape RectangularArea :: Boundingbox ()
const forme.h: 21: Remarque: virtuel
Forme * forme :: clone () const
forme.h: 55: Remarque: vide virtuel
Forme :: Dessin (graphiques &) const p>
blockQuote> Alors, quel est le moyen idéal de stocker ces formes. Quel type de collection devrais-je utiliser pour stocker ces choses? p> merci p> p>
3 Réponses :
Lorsque vous avez besoin de polymorphisme, vous devez utiliser des pointeurs ou des références. Puisque les conteneurs (ou les tableaux) ne peuvent pas stocker des références, vous devez utiliser des pointeurs.
modifier essentiellement le vecteur de votre classe d'image sur: p> et modifier correctement l'autre membre Fonctions. P> La raison pour laquelle vous ne pouvez pas / ne pas les stocker comme des types de valeur est parce que le vecteur est un conteneur homogène, c'est-à-dire qu'il stocke uniquement les données d'un type (et seulement em> em> Un type - les sous-classes ne sont pas autorisées!). La raison en est que le vecteur stocke ses données dans une matrice, qui doit connaître la taille des objets qu'il stocke. Si les tailles de ces objets sont différentes (elles pourraient être pour différentes formes), il ne peut pas les stocker dans un tableau. P> Si vous les stockez comme des pointeurs, ils ont tous la même taille ( Tailleof (forme *) code>) et ont également accès à la table de la forme, ce qui permet un comportement polymorphe. p> p>
Avec les fonctionnalités C ++ 0X telles que les pointeurs intelligents améliorés et déplacez la sémantique, on pourrait même créer une version de sécurité-sécurité de cette ( vecteur
Si vous n'utilisez pas les pointeurs intelligents, rappelez-vous que le conteneur ne nettoie pas automatiquement les données pointues. Il appelle les destructeurs sur les pointeurs - mais ces destructeurs ne font rien. Vous devriez ajouter un destructeur à votre classe d'images qui iTère à travers les formes les supprimant. En utilisant une classe de pointeur intelligente, comme le suggère BobbymCr, évite ce problème.
Utilisez des types de retour covariant. Voir FAQ 20.8 pour votre En outre, vous ne pouvez pas avoir de conteneur d'objets de classe abstraite, les classes abstraites ne peuvent pas être instanciées. Au lieu de cela, créez un conteneur de pointeurs / références à des objets en béton dérivés. Remarque, si vous utilisez un pointeur, il devient de votre responsabilité de les effacer. Le conteneur ne désactivera pas correctement la mémoire. Vous pouvez utiliser des pointeurs intelligents au lieu des pointeurs bruts pour le gérer plus efficacement. RECHERCHEZ clone code> méthodes. Vous pouvez également compter sur la méthode d'usine également pour créer les objets code> de forme code>. P>
SCOPED_PTR CODE> ET
SHARED_PTR CODE> de BOOST. P>
En premier écrémé, j'ai vu les "types de retour de covariant" et supposé que cela répondait à la mauvaise question. Après que la réponse principale ait peut-être gagné, vous avez gagné plus de upvotes. Vous avez mon +1 maintenant.
Comme déjà décrit dans un autre polymorphisme de réponse nécessite des références ou des pointeurs. Au lieu de l'allocation de mémoire brute, vous pouvez utiliser des pointeurs intelligents. Vous pouvez créer un conteneur avec et ajouter des éléments avec p> la mémoire est libérée lorsque le vecteur est détruit. P> p>
Serait-ce emplace_back code> ou
push_back code>? Si les deux sont valides,
push_back code> peut avoir plus de sens, car
emplace_back code> suggère que vous passez un
unique_ptr
@Nathanpierson Vous avez probablement raison. Les deux sont possibles pour que je vais le changer.