IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

operator = implicitly deleted : Que faire ?


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juillet 2018
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2018
    Messages : 27
    Points : 27
    Points
    27
    Par défaut operator = implicitly deleted : Que faire ?
    Bonjour la comunauté,

    Je souhaite retirer (et détruire) un objet de la classe Objet d'un conteneur vector "listObjet" avec le code suivant (i est un unsigned int < listObjet.size()):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listObjet.erase(listObjet.begin() + i);
    J'obtiens le message d'erreur suivant :

    error: use of deleted function 'Objet& Objet::operator=(const Objet&)
    'Objet& Objet::operator=(const Objet&)' is implicitly deleted because the default definition would be ill-formed
    Je reste perplexe sur le sens à donner à ces messages (et à ce qu'il faudrait faire pour remédier à la situation).
    Pourriez vous m'éclairer svp ?

    Rick.

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 562
    Points : 7 628
    Points
    7 628
    Par défaut
    Bonjour,

    Pour enlever un élément dans une table, le seul moyen et de copier les Objet pour combler le trou correspondant à l’élément disparaissant.
    Mais Objet est un objet non copiable, cette opération est donc impossible.

    Alors :
    a) il faut voir pourquoi Objet est non copiable et remédier en le rendant copiable
    b) ou ne pas utiliser un std::vector<Objet> mais plutôt un std::list<Objet>. Ce type de conteneur supporte de stocker des objets non copiables mais on y perdra des capacités (par exemple listObjet.begin()+i n'est pas possible.)
    c) ou utiliser un vector de pointeurs ou de std:reference_wrapper sur des Objet qui n'aura qu'à copier les pointeurs au lieu de la copie impossible des Objet.

    La solution (a) est peut-être préférable. Si tu ne vois pas pourquoi Objet n'est pas copiable donne nous la déclaration de Objet.

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,
    Citation Envoyé par dalfab Voir le message
    La solution (a) est peut-être préférable. Si tu ne vois pas pourquoi Objet n'est pas copiable donne nous la déclaration de Objet.
    Ben, rien qu'à voir le nom, j'aurais tendance à dire que Objet est une classe de base servant pour une multitude de classe dérivée (un God Object, en somme), ce qui justifierait sans doute pleinement qu'il ne soit pas copiable.

    Dans cette optique, je pencherais d'avantage pour la solution C

    Ceci étant dit, je suis particulièrement frileux à l'idée de créer une classe Objet destinée à servir de classe de base à toutes les autres, surtout en C++ (*), car il faut retenir que l'héritage multiple se doit de respecter le LSP, si bien que tous les services rendus par la classe de base (faisons simple : les fonctions publiques qu'elle exposent) doivent être valide pour l'ensemble des classes dérivées, y compris pour les classes ne dérivant de Objet que de manière (peut-être très) indirecte.

    Or, j'ai beau me creuser la cervelle, je n'arrive pas à imaginer un service qui sera valable à la fois pour un compte en banque et pour un animal, par exemple (et on pourrait étendre la liste à l'envi).

    (*) bien que je comprenne les motivations qui ont poussé les développeurs de java ou de C# à créer une telle classe, car c'est elle qui permet au ramasse miettes de fonctionner correctement. Comme il n'y a pas de ramasse miettes en C++, la seule raison plausible (bien que discutable) d'avoir une telle classe est purement et simplement nulle et non avenue
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Juillet 2018
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2018
    Messages : 27
    Points : 27
    Points
    27
    Par défaut
    Tout d'abord merci pour ces réponses, elles éclairent le sujet.

    Effectivement je pense que la solution c, un vecteur de pointeur (smart bien sûr, probablement un vecteur de "unique_ptr") doit être une bonne solution.
    J'avais plus ou moins ça en tête mais avant de la mettre en œuvre, je voulais comprendre la raison de ces messages.

    Ma classe "Objet" (Objet est un pseudo en fait) n'est ni une classe mère ni une classe hérité.
    Cependant elle contient deux autres classes, elle est donc une composition.
    Peut être est-ce là la raison du fait qu'elle soit non copiable ?

    Le reste les attributs sont des int des bool, une enum class et des conteneurs vector et map.
    Je veux bien joindre les headers de ces classes mais j'ai peur qu'elles soient si maladroitement construites (je fais tout ça en autodidacte) que cela dissuade quiconque de s'y intéresser...
    En plus, je les modifie quotidiennement pour les optimiser au fur et à mesure de mes progrès en c++.

    Rick.

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par Rick_Cplusplus Voir le message
    Ma classe "Objet" (Objet est un pseudo en fait) n'est ni une classe mère ni une classe hérité.
    Cependant elle contient deux autres classes, elle est donc une composition.
    Peut être est-ce là la raison du fait qu'elle soit non copiable ?
    Pas forcément, du moins, pas de manière directe.

    A priori, si tu obtiens un message de ce genre, c'est parce que la définition de ta classe ressemble à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Machin{
    public:
        Machin(Machin const &) = delete;
        Machin & operator = (Machin const &) = delete;
    };
    Mais, pour pouvoir copier une classe, il faut être capable... d'en copier le contenu. Si ta classe est une composition, et qu'elle prend la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Machin{
    private:
        Brol leBrol;
        Bidule leBidule;
    };
    tu ne pourra -- forcément -- copier l'instance de la classe Machin que ... si tu peux copier les données membres leBrol et leBidule. Si, pour une raison ou une autre, la classe Brol ou la classe Bidule ne peut pas être copiée, il devient forcément impossible de copier la classe Machin.

    Et, bien sur, on peut remonter très loin comme cela, car, il se peut que tu ne puisse en réalité pas copier la classe Brol à cause ... d'une de ses données membre qui ne peut pas être copiée, et ainsi de suite jusqu'à n'en plus finir
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Les PC sont de plus en plus bruyants que faire
    Par plichtal dans le forum Ordinateurs
    Réponses: 260
    Dernier message: 23/12/2011, 13h28
  2. Après l'initrd, que faire ?
    Par Michaël dans le forum Administration système
    Réponses: 10
    Dernier message: 02/09/2004, 19h02
  3. [Q] que faire quand un plugin n'apparait pas dans eclipse
    Par zolive dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 31/08/2004, 00h38
  4. [DirectDraw] Que faire pour optimiser le rendu ???
    Par mat.M dans le forum DirectX
    Réponses: 8
    Dernier message: 12/12/2003, 19h02
  5. [maintenance][performance] Que faire comme maintenance ?
    Par woodwai dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 06/11/2003, 16h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo