Pour copier un std::vector il y a bien plus simple:
EDT::EDT(EDT const& edt) : _liste(edt._liste)
{
}
Le 'égal' marche très bien! Et revient à faire exactement ce que tu as écrit! Si tu as un problème ça doit être dans ce que tu présentes derrière le Enseignement*. Tu sembles gérer de la mémoire dynamique directement, ce qu'il ne faut normalement jamais faire!
Je n'ai pas pris l'option de la simple assignation parce que je n'ai pas envie que mes nouveaux pointeurs pointent juste vers le même objet que mon vector de base.
Ma classe Enseignement est abstraite, et mon vector simplement constitué de pointeurs vers des Enseignements, je ne vois pas où est le problème
Tu te prends la tête pour rien et des personnes, plus expérimenté que toi à première vue, ont fait en sorte que l'opérateur égal fonctionne correctement (quand on suit les best practices, dont ne pas gérer la mémoire à la main).
Tu utilises des pointeurs nus et du n'est pas "aware" sur le concept d'ownership, ça sent pas bon.
Je pense que vous devriez revoir l'ownership et les pointeurs intelligents avant de vous faire péter un anévrisme au cerveau, pour rien.
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Je n'ai pas pris l'option de la simple assignation parce que je n'ai pas envie que mes nouveaux pointeurs pointent juste vers le même objet que mon vector de base.
Ce que tu fais revient à copier tous les éléments du vecteurs donc est totalement identique à copier directement le vecteur. Tu ne veux pas que les pointeurs pointent au même endroit donc tu considères que c'est toi qui gère les allocations dynamiques et donc c'est à toi de ne pas copier directement pointeurs; mais il faut faire une allocation qui sera la copie et mémoriser ce nouveau pointeur. Il ne faut normalement jamais gérer cela directement car il existe des tas de moyens beaucoup plus sûr.
Ce que tu veux (mais si un de mes élèves fait ça il se fait taper sur les doigts) :
EDT::EDT( EDT const& edt ) {
for ( Enseignement* x : edt ) {
_liste.push_back( new Enseignement(*x) );
}
} // J'ai dû supposer que Enseignement* représente un pointeur alloué par new et que l'objet Enseignement est copiable
ncRakl a écrit:
Ma classe Enseignement est abstraite, et mon vector simplement constitué de pointeurs vers des Enseignements, je ne vois pas où est le problème
Vois-tu maintenant le problème? Quand on écrit Enseignement*, il n’apparaît aucune information sur la manière d'allouer et copier les Enseignements. A toi d'y penser partout. Exemple de code qui pose un problème :
EDT edt1;
EDT edt2;
// ... ... ... remplir edt1 ... ... ...
edt2 = edt1; // => problème car on ne passe pas par le constructeur de copie
Pourquoi est-ce que Enseignement est stocké sous forme de pointeur brut ? S'il est propriétaire de la mémoire c'est qu'il y a un problème
Sauf cas de force majeur et si Enseignement est un objet polymorphe il ne devrait pas être copiable car c'est une entité
Si ce n'est pas un objet polymorphe il suffit de le stocker sous forme de variable simple, pas de smart-pointeurs nécessaire (et les copies/déplacements seront automatiques).
git is great because Linus did it, mercurial is better because he didn't.
En effet, un objet polymorphe n'a normalement pas vocation à être copié.
Si tu ne veux pas t'emmerder, utilise des std::shared_ptr
std::shared_ptr<UnObjetPolymorphe>
Ainsi quand tu veux recopier un objet qui contient un objet ou un tableau d'objets polymorphes ça se copie tout seul, (tout en pointant sur le même), ça se désalloue tout bien, ça fait la sauce correctement au niveau de la mémoire, ça se manipule simplement.
Peut-être ce n'est pas ce dont souhaite l'auteur. Le shared_ptr copié pointe toujours sur le même objet. Si le but est de faire une copie profonde le problème est toujours là.
git is great because Linus did it, mercurial is better because he didn't.
Dés le moment où tu as écrit cette phrase, tu as scellé ton destin: Ta classe Enseignement est une classe qui a sémantique d'entité.
Cela signifie qu'elle ne peut EN AUCUN CAS être copiée. Il n'y a pas à aller plus loin!!! Parce que tu ne veux en aucun cas risquer de te retrouver, à un moment donné de l'exécution, avec deux instances représentant de l'enseignement XXX qui auraient évolué différemment.
(C'est ce que Fvirtman a dit deux interventions plus haut, je me contente d'expliquer de manière plus explicite )
A partir de là, il faut que tu fasse une distinction très claire entre les éléments qui ne font que manipuler tes enseignements (mais qui ne peuvent décider ni d'en créer de nouveau, ni de détruire les existants), et ce qui va prendre la responsabilité spécifique de les maintenir en mémoire "aussi longtemps que nécessaire.
S'il n'y a qu'un seul élément qui prend en charge la création, le maintient en mémoire et la destruction des différentes instance de la classe Enseignement, tu as -- très largement -- intérêt à utiliser les std::unique_ptr (*), et à veiller à les transmettre (aux éléments qui ne font que les manipuler) sous la forme de référence, voir, sous forme de référence constantes, si celui qui les manipule ne cherche pas à les modiier.
Dans de rares cas, plusieurs éléments doivent agir "d'un commun accord" pour assurer l'existence des différentes instances de Enseignements. On peut alors éventuellement envisager le fait de les maintenir en mémoire sous forme de std::shared_ptr. Mais cette solution ne devrait être utilisée qu'en tout dernier recours
Fvirtman a écrit:
Il y a probablement un problème de conception en amont.
C'est même bien plus que "probablement": Il y a clairement un problème de conception
markand a écrit:
Peut-être ce n'est pas ce dont souhaite l'auteur. Le shared_ptr copié pointe toujours sur le même objet. Si le but est de faire une copie profonde le problème est toujours là.
Dis toi bien que ce que souhaite l'auteur n'a plus la moindre importance, vu qu'il se trouve face à une incohérence majeure: il essaye d'utiliser une classe ayant sémantique d'entité comme si elle avait en réalité sémantique de valeur.
C'est comme si tu voulais avoir de la glace bouillante ou de la lave (encore liquide, mais) gelée. Les deux concepts sont à se point incompatibles qu'il n'y a pas d'autre solution que de revoir sa copie
On a beau être gentil et tout ce que l'on veut, il nous est impossible de tergiverser sur ce point
- Edité par koala01 6 décembre 2019 à 18:08:42
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Erreur avec vecteur de pointeurs
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
En recherche d'emploi.
En recherche d'emploi.
git is great because Linus did it, mercurial is better because he didn't.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
git is great because Linus did it, mercurial is better because he didn't.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html