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 :

Questions sur conception générale


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Ingénieur Etudes
    Inscrit en
    Juillet 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur Etudes

    Informations forums :
    Inscription : Juillet 2010
    Messages : 54
    Points : 72
    Points
    72
    Par défaut Questions sur conception générale
    Bonjour,

    Je suis en pleine réflexion sur l'architecture de mon projet au boulot et j'ai besoin de gens qui ont du recul pour m'aider.

    Par exemple, mes classes ont des membres pointeurs sur des classes (pas des pointeurs sur des types primitifs). Des pointeurs à l'ancienne hein, pas des smart, pas pour le moment.

    Et du coup j'ai dû appliquer la Rule of Five : mettre un destructeur personnalisé et expliciter les constructeurs de copie, de move et les opérateurs correspondants.

    Maintenant, j'aimerais juste interdire la copie. Mais en forçant le delete sur le constructeur de copie et l'opérateur, est ce que je peux garder les move constructor et le destructor ? Ça ne viole pas la règle ?

    Ensuite, je me demande comment faire un setter d'un membre "pointeur" proprement. Oui je sais, c'est le mal les getters et setters mais admettons que je veuille le faire, comment m'y prendre ? Est ce que je fais juste ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void setToto(const int &toto)
    {
        *m_toto = toto;
    }
    Ou un truc plus compliqué ?


    Et enfin, j'ai cru lire que remplir un vecteur de pointeurs c'était plutôt dangereux avec des push_back de new car on risque de perdre le contenu si l'allocation échoue. Quelle est alors la meilleure alternative ?

    Merci à vous si vous prenez le temps de répondre à mes questions.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par fanzilan Voir le message
    Ensuite, je me demande comment faire un setter d'un membre "pointeur" proprement.
    Tu n'as que 2 copies :
    • "shallow copy". Avec 1 pointeur, c'est ce que tu as fait : une affectation. Le problème, tu as maintenant 2 propriétaires pour le même objet.
    • "deep copy". Pointeur ou pas, tu as 2 objets identiques. Le problème est que lors de la modification de l'1, il faudrait éventuellement modifier l'autre (pour synchroniser).

    À moins que tu détruises l'original : c'est équivalent à 1 déplacement.


    Édit :
    Citation Envoyé par AbsoluteLogic Voir le message
    c'est pas une "deep copy" du coup ? L'affectation appelle actuellement l'affectation par copie de m_toto si je ne m'abuse.
    Oui tu as raison c'est 1 affection entre 2 objets et non entre 2 pointeurs. Donc, oui c'est l'opérateur = qui peut rentrer en compte.

  3. #3
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2018
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juillet 2018
    Messages : 95
    Points : 212
    Points
    212
    Par défaut
    Bonjour,

    Citation Envoyé par fanzilan Voir le message
    Maintenant, j'aimerais juste interdire la copie. Mais en forçant le delete sur le constructeur de copie et l'opérateur, est ce que je peux garder les move constructor et le destructor ? Ça ne viole pas la règle ?
    J'ai envie de dire que non, ce n'est pas un problème, c'est ce que l'on fait lorsqu'on veut assurer l'unicité d'un propriétaire, comme le ferait le pointeur intelligent std::unique_ptr.

    Citation Envoyé par fanzilan Voir le message
    Ensuite, je me demande comment faire un setter d'un membre "pointeur" proprement. Oui je sais, c'est le mal les getters et setters mais admettons que je veuille le faire, comment m'y prendre ? Est ce que je fais juste ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void setToto(const int &toto)
    {
        *m_toto = toto;
    }
    Ou un truc plus compliqué ?
    A mon humble avis, tout ce qui compte, c'est d'empêcher l'utilisateur de ta classe d'amener des comportements qui ne sont pas prévus. Donc du moment que tu mets des consts aux bons endroits et que tu fais bien attention à ce qui est une référence est ce qui est une valeur, tu fais ce que tu veux. Comme le dit foetus, il faut distinguer une copie d'une affectation de référence. Mais par contre @foetus, c'est pas une "deep copy" du coup ? L'affectation appelle actuellement l'affectation par copie de m_toto si je ne m'abuse.

    Citation Envoyé par fanzilan Voir le message
    Et enfin, j'ai cru lire que remplir un vecteur de pointeurs c'était plutôt dangereux avec des push_back de new car on risque de perdre le contenu si l'allocation échoue. Quelle est alors la meilleure alternative ?
    J'avoue que je ne me suis jamais posé de telles questions parce que si le push_back échoue dynamiquement, je considère que j'ai de plus gros problèmes que ça Si malgré tout, tu veux bien gérer ce cas, soit tu rajoutes du code pour faire ça en plusieurs étapes, et désallouer si il y a un pb, soit tu utilises les pointeurs intelligents qui feront très bien leur travail.

    Voilà, tu as eu l'avis de quelqu'un qui se soucie beaucoup moins des détails que toi visiblement , je te laisse en penser ce que tu veux, ou je laisse quelqu'un me dire que je racontes n'importe quoi.

  4. #4
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    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 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Appliquer le rule of five sans se tromper est un travail titanesque, je ne m'y risquerais pas.
    Ton objet reçoit des pointeurs bruts, ou bien il en devient le responsable et il suffit de les stocker dans un std::unique_ptr<> ou bien il ne l'est pas et il suffit de les stocker dans un pointeur brut.
    Et du coup, rien à faire dans le destructeur et les constructeur/operateur de copie/déplacement. Et du coup rien à faire pour interdire la copie, un objet qui contient des std::unique_ptr<> est automatiquement non copiable.

    Le code que tu donnes n'a aucun rapport avec la gestion des pointeurs, tu veux stocker une donnée et tu te sers d'un pointeur. Pourquoi un pointeur si tu souhaites garder une instance?

    Si par contre, ton objet doit mémoriser des références (ou des pointeurs) vers des entités. Tu dois distinguer les 2 cas:
    Tu deviens le responsable de l'objet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void setTotoResponsable(const int &toto) // c'est l'appelant qui a fait new, ton objet doit s'occuper du delete
    {
        m_unique_ptr_sur_l_int_toto.reset( &toto );  // le unique_ptr<> en devient responsable
    }
    Tu n'es pas le responsable de l'objet reçu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void setTotoPasResponsable(const int &toto)
    {
        m_pointeur_brut_sur_l_int_toto = &toto; // gérer la vie de toto n'est pas mon problème
    }
    Et ton exemple où tu souhaites garder une copie de l'instance:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void setTotoCopie(const int &toto)
    {
        m_une_copie_d_un_toto = toto; // il y a maintenant 2 toto.
    }
    Quant à ton interrogation sur un tableau de pointeurs. Si tu en es responsable, c'est un tableau de std::unique_ptr<>, sinon un tableau de pointeurs bruts. Et s'il y a erreur d'allocation, ça va provoquer une exception qui va arrêter ton appli, et tous les problèmes disparaîtront avec.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par fanzilan Voir le message
    Des pointeurs à l'ancienne hein, pas des smart, pas pour le moment.
    C'est dommage, parce que c'est sûrement la chose la plus importante à faire.
    Et ça permet facilement de trouver où les erreurs du type copier un machin qui le devrait pas se trouvent. Et à la compilation qui plus est.

    Citation Envoyé par fanzilan Voir le message
    Mais en forçant le delete sur le constructeur de copie et l'opérateur, est ce que je peux garder les move constructor et le destructor ? Ça ne viole pas la règle ?
    C'est le principe même de unique_ptr.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre régulier
    Homme Profil pro
    Ingénieur Etudes
    Inscrit en
    Juillet 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur Etudes

    Informations forums :
    Inscription : Juillet 2010
    Messages : 54
    Points : 72
    Points
    72
    Par défaut
    Merci pour vos réponses !

    Donc effectivement je vais passer aux smart pointeurs dès que possible. Mais j'hésitais entre un shared et un unique...

    @dalfab : il s'agit de classes façon "container" qui vont contenir donc à l'intérieur d'autres classes différentes qui eux même etc...comme des poupées gigognes, jusqu'à ce que le dernier containeur lui contienne des valeurs et pas des pointeurs.

    Donc je préfère contenir des pointeurs vers ces classes. Mais peut-être que je me trompe.

    Je ne sais pas encore si dans la version finale je suis "responsable" de mes objets mais pour mes tests oui.

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

Discussions similaires

  1. Questions sur conception de ma BDD
    Par Nandou56 dans le forum MS SQL Server
    Réponses: 0
    Dernier message: 10/03/2010, 10h05
  2. Réponses: 3
    Dernier message: 11/06/2006, 12h09
  3. [VB.net] Question sur conception
    Par arno2000 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 14/04/2006, 08h35
  4. [Conception] Question sur un code permettant de connaître le nombre de connectés
    Par inferno66667 dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 19/12/2005, 19h49
  5. Réponses: 24
    Dernier message: 29/08/2005, 13h33

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