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

Langage C++ Discussion :

delete de tableau dynamique à 2 dimensions


Sujet :

Langage C++

  1. #1
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut delete de tableau dynamique à 2 dimensions
    Bonjours à tous, je suis sur la construction d'un petit moteur 2d et je n'arrive pas à savoir si la mémoire allouée est bien vidée, pouvez vous me l'affirmer ou me corriger si possible, merci ! (tableau 2 dimensions de type char)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    ///SOURCE
    #include "Quad.h"
     
    //INITIALISATION
    Quad::Quad(const int width, const int height)
    {
    //Dimensions du Quad
        this -> width = width;
        this -> height = height;
     
    //Création du tableau de char : quad[largeur][hauteur]
        quad = new unsigned char *[width];
        for(int x = 0; x < width; x++)
            quad[x] = new unsigned char [height];
    }
     
    //DESTRUCTION
    Quad::~Quad()
    {
    //Vidage de la mémoire
     
        for(int y = 0; y < height; y++)
            delete[] quad[y];
        delete[] quad;
     
    }
     
     
     
    ///Header
    #ifndef QUAD
    #define QUAD
     
    class Quad
    {
    public:
        //INITIALISATION
        Quad(const int, const int);
        ~Quad();
     
        //QUAD PROPRETY
        inline int GetWidth() { return width; }
        inline int GetHeight() { return height; } }[(int)y] = stat; }
     
    private:
        unsigned char **quad;
        int width, height;
    };
     
    #endif // QUAD

  2. #2
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par PilloBuenaGente Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    //Création du tableau de char : quad[largeur][hauteur]
        quad = new unsigned char *[width];
        for(int x = 0; x < width; x++)
            quad[x] = new unsigned char [height];
    }
     
    //DESTRUCTION
    Quad::~Quad()
    {
    //Vidage de la mémoire
     
        for(int y = 0; y < height; y++)
            delete[] quad[y];
        delete[] quad;
     
    }
    Ya un soucis sur le destructeur, tu crée un tableau de taille [width][height], mais tu le détruit comme un tableau de taille [height][width]

  3. #3
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Les "height" sont créés à partir des "width", pour l'effacement je ne dois pas en premier supprimer les "height" ? Je risque de perdre les pointeurs non ?

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    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 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    La règle est simple, il faut autant de delete que de new.
    Tu as 1 + width new, et height + 1 delete -> problème.
    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.

  5. #5
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Celui ci est sans doute plus vrai !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    //CONTRUCTION
    {
        quad = new unsigned char *[width];
        for(int x = 0; x < width; x++)
            quad[x] = new unsigned char [height];
    }
     
    //DESTRUCTION
    Quad::~Quad()
    {
        for(int x = 0; x < width; x++)
            delete[] quad[x];
        delete[] quad;
    }
    Merci à vous, je pense être en mesure maintenant d'éviter toute perte !

  6. #6
    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,

    Ceci dit, si tu dois réellement avoir un tableau deux dimensions "plein" (dans le sens où toutes les "cases" sont utilisées), il est souvent utile et préférable de travailler d'une manière alternative:

    Si tu y réfléchis trente secondes, en demandant d'avoir un tableau de nLines lignes et de nCols colonnes, tu espères, tout simplement, obtenir un tableau de nLines * nCols éléments.

    En travaillant comme tu le fais, tu te places dans une situation dans laquelle :
    1. tu multiplie les risques d'échec d'une allocation dynamique (tu te retrouves à faire 1+ ligne allocations, et chacune d'elle peut échouer)
    2. tu dois impérativement veiller à libérer la mémoire dans un ordre particulier
    3. tu cours le risque d'une "fragmentation" importante des données en mémoire
    4. tu dois gérer, selon les circonstances, des pointeurs de pointeurs ou des pointeurs
    Il est donc souvent opportun de se dire que, finalement, si tu veux nLines * nCols éléments, il te "suffit" de demander une seule allocation "globale" de... nLines * nCols éléments

    Par la suite, lorsque tu voudras accéder à l'élément se trouvant à la ligne X et à la colonne Y, il te suffira d'accéder à l'élément (X * nCols) + y .

    Tu aurais donc un code proche de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    class Quad
    {
    public:
        //INITIALISATION
        Quad(const int, const int);
        ~Quad();
     
        //QUAD PROPRETY
        /* 1- inline est implicite quand on définit une fonction membre directement
        * dans la définition d'une classe
        * 2- toute fonction qui ne doit en aucun cas modifier l'objet devrait
        * etre déclarée constante pour pouvoir être utilisée également depuis 
        * des objets constants ;)
        *
        */
        int GetWidth() const { return width; }
        int GetHeight() const { return height; }
        char get(int line, int col) const
        {
            return quad(line * height + col);
        }
    private:
        unsigned char *quad;
        int width;
        int height;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    /* cela ne change pas grand chose ici, mais il vaut mieux recourir à la "liste
     * d'initialisation"...
     * cela prend toute son importance lorsque les membres d'une classe / structure
     * sont des objets "complexes" (demandant du temps et / ou des ressources
     * lors de leur création)
     *
    */
    Quad::Quad(const int width, const int height):width(width), height(height),
              quad(new char [width * height])
    {
     
    }
     
    //DESTRUCTION
    Quad::~Quad()
    {
    //Vidage de la mémoire
        delete[] quad;
     
    }
    NOTA:

    Il reste un détail à régler, car on n'y a pas encore fait allusion dans cette discussion...

    Pour l'instant, tu es en mesure d'éviter les fuites mémoire lors d'une utilisation "simple" du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
        Quad obj(5,10);
        /* on n'utilise que obj ici */
        return 0;
    }
    Mais, que se passera-t-il, selon toi, si on en arrive à une utilisation proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void foo(Quad quad)
    {
        /* ici, on travaille avec quad, qui est une copie de l'objet passé en paramètre */
    }
    int main()
    {
         Quad obj(5,10);
         foo(obj);
         return 0;
    }


    Je vais te laisser réfléchir un tout petit peu à la question et, au besoin, l'expérimenter

    Une chose est sur, tu te trouveras confronté à un problème qu'il faudra prendre en compte . Mais ca, ce sera pour une intervention ultérieure
    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

  7. #7
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Merci tout d’abord pour le temps que tu m'accordes. Je suis sur ce programme depuis mes début en programmation(1an environ) Je suis à un moment donné effectivement passé par quad[largeur * hauteur]. Ce "Quad" peut être d'une valeur importante (1000 / 1000) (si c'est important...) et sera en deux ou trois exemplaires. Aussi un tableau de même taille est utilisé pour ranger des pointeurs. Je pensait du coup permettre un rangement plus flexible en mémoire.

    Pour envoyer mes Classe de tableau je n'utilise que des références:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main()
    {
         Quad obj(5,10);
         Foo foo(obj);
         return 0;
    }
    Que je distribue à des pointeurs:
    .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Foo
    {
    public:
         Foo(Quad &);
    private:
         Quad *quad;
    }
    .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include "Foo.h"
     
    Foo::Foo(Quad &quad) : this -> quad = quad;
    {
     
    }
    Peut être ma méthode est elle mauvaise. Bon aprèm' !

  8. #8
    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 PilloBuenaGente Voir le message
    Pour envoyer mes Classe de tableau je n'utilise que des références:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main()
    {
         Quad obj(5,10);
         Foo foo(obj);
         return 0;
    }
    Que je distribue à des pointeurs:
    .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Foo
    {
    public:
         Foo(Quad &);
    private:
         Quad *quad;
    }
    .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include "Foo.h"
     
    Foo::Foo(Quad &quad) : this -> quad = quad;
    {
     
    }
    Peut être ma méthode est elle mauvaise. Bon aprèm' !
    Heu, je présumes que tu voulais écrire soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Foo::Foo(Quad &quad) :quad(& quad)
    {
     
    }
    soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Foo::Foo(Quad &quad) : 
    {
        this -> quad = & quad;
    }
    autrement, cela ne compilera pas

    Mais le problème reste néanmoins complet, et tu n'as pas répondu à la question sous-jacente : que se passera-t-il, selon toi, si tu te trouves dans une situation où, que ce soit volontairement ou non, tu effectue une copie ou une affectation de ta classe Quad

    Et cette question en amène une autre : Est-il simplement opportun d'accepter la copie et / ou l'affectation de ta classe

    Pour te mettre sur la voie de la deuxième question, tu devrais réfléchir à la sémantique de ta classe Quad (je ne connais pas assez ton projet pour y donner une réponse ) mais, si ta classe Quad a sémantique d'entité , tu devrais prendre des mesures pour la rendre non copiable et non assignable.

    Par contre, si ta classe a sémantique de valeur, tu devrais redéfinir le constructeur par copie et l'opérateur d'affectation.

    Mais, avant d'en arriver à t'expliquer le pourquoi, j'aimerais te laisser une chance de le comprendre par toi meme
    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

  9. #9
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Et moi qui commençais à croire que je commençais à comprendre....

    J'ai en effet, merci, découvert le "pattern singletone" !

    Je dois avouer que ça aide pas mal a construire tout ça !
    .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    #ifndef QUAD_H_INCLUDED
    #define QUAD_H_INCLUDED
     
    class Quad
    {
    public:
        //GET ONLY QUAD
        static Quad& GetQuad();
     
    private:
        //SINGLETONE
        Quad(const Quad&);
        Quad & operator = (const Quad&);
     
    	//INITIALISATION DESTRUCTION
    	Quad(const int, const int);
    	~Quad();
     
    	//SIZE OF QUAD
    	const int width;
    	const int height;
    };
     
    #endif // QUAD_H_INCLUDED
    .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    #include "Quad.h"
     
    #include "Configuration.h"
    //GET ONLY QUAD
    Quad &Quad::GetQuad()
    {
        static Quad quad(DEFAULT_WIDTH_SCREEN, DEFAULT_HEIGHT_SCREEN);
        return quad;
    }
    //INITIALISATION
    Quad::Quad(const int w, const int h) : width(w), height(h)
    {}
    //DESTRUCTION
    Quad::~Quad()
    {}
    Classe non duplicable et objet facilement récupérable !
    Et on repart du début !
    (mais mieux, ...si je ne me suis pas planté)
    Merci !

  10. #10
    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
    Deux choses :

    Le constructeur et le destructeurs se doivent d'être publiques, autrement, tu n'auras aucun moyen de créer des variables du type Quad.

    Ensuite, le pattern singleton , c'est autre chose : il s'agit d'une classe dont on est sur qu'il n'existera jamais qu'une et une seule instance durant toute l'exécution du programme.

    C'est d'ailleurs un pattern fort décrié (à raison selon moi) car il a pour conséquence la création d'une variable globale, meme si elle le cache bien (or, les variables globales, c'est mal ) et qu'il est souvent le symptome du fait que tu as peut etre fort mal évalué les interactions qu'il peut y avoir entre une classe et "le reste du programme"
    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

  11. #11
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Pardon, celle ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Foo::Foo(Quad &quad) : 
    {
        this -> quad = & quad;
    }
    Pour te mettre sur la voie de la deuxième question, tu devrais réfléchir à la sémantique de ta classe Quad (je ne connais pas assez ton projet pour y donner une réponse ) mais, si ta classe Quad a sémantique d'entité , tu devrais prendre des mesures pour la rendre non copiable et non assignable.
    Elle a une sémantique d'entité. A part redéfinir l’opérateur par copie je ne vois pas comment procéder.

    Je ne travail qu'avec des classes, peut être que là est le problème?!

    tu as peut etre fort mal évalué les interactions qu'il peut y avoir entre une classe et "le reste du programme"
    C'est sans doute vrai, j'ai l'impression de tourner en rond depuis longtemps sur "comment mon programme doit être organisé". J'obtiens un "truc" qui tourne mais trop désordonné.

  12. #12
    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 PilloBuenaGente Voir le message
    Pardon, celle ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Foo::Foo(Quad &quad) : 
    {
        this -> quad = & quad;
    }

    Elle a une sémantique d'entité. A part redéfinir l’opérateur par copie je ne vois pas comment procéder.

    Je ne travail qu'avec des classes, peut être que là est le problème?!
    Attends, reprenons :

    Une classe a sémantique de valeur s'il est possible de trouver deux instances différentes de cette classe en mémoire présentant exactement les même valeurs et pouvant être considérées comme identique (par exemple : une couleur, un point, ...)

    Ces classes sont, généralement, copiables, assignables, comparables par égalité (parfois par inégalité), constantes (la modification d'une des valeurs qui les composent occasionne l'obtention... d'une nouvelle instance de cette classe) et ne sont pas adaptées à un héritage.

    Une classe a sémantique d'entité si tu ne peux pas avoir deux instances différentes de cette classe en mémoire présentant exactement les même valeurs car certaines des valeurs utilisées permettent d'identifier chaque instance de manière unique et non ambigue (par exemple : un compte bancaire, une personne, ...).

    Ces classes ne sont pas copiables ni assignables, disposent de comportements susceptibles d'en modifier certains états, et sont généralement susceptibles d'être héritée (dans les limites du LSP, évidemment ).

    Pour éviter qu'une classe soit copiable ou assignable, il faut:
    • Soit déclarer le constructeur par copie (respectivement l'opérateur d'affectation "=" ) dans l'accessibilité privée sans le définir (ancienne méthode)
    • Soit, si le compilateur supporte cette fonctionnalité de C++11, faire suivre le constructeur par copie (respectivement l'opérateur d'affectation) du mot clé delete sous la forme de MaClass(MaClass const &) = delete; ou de MaClass & operator=(MaClass const &) = delete;
    (Note : A l'heure actuelle, cette possibilité n'est toujours pas supportée par VC++, y compris dans sa version 2012 )

    Le fait que tu ne travailles qu'avec des classes ne changera rien à la sémantique donnée à chacune d'elle, si ce n'est que toute classe manipulant en interne une instance de classe ayant sémantique d'entité aura, fatalement, sémantique d'entité elle aussi
    C'est sans doute vrai, j'ai l'impression de tourner en rond depuis longtemps sur "comment mon programme doit être organisé". J'obtiens un "truc" qui tourne mais trop désordonné.
    En fait, je parlais de manière générale du concept de singleton là :

    Généralement, une classe qui devra être utilisée "n'importe où dans le code" est souvent le symptôme du fait que tu auras très mal séparé les différents problèmes les uns des autres et que tu as, sans doute, très mal séparé les différentes responsabilités

    Mais, si tu as l'impression de "tourner en rond", il est peut etre utile de repenser un peu à ta conception de base

    Généralement, ce que je fais lorsque je dois concevoir quelque chose, c'est de commencer par exprimer (en français courent) clairement les différents besoins auxquels je suis confrontés.

    Chaque fois que je me trouve face à un terme qui mérite d'être expliqué, je l'explique spécifiquement.

    Une fois que j'ai effectué ce travail, je pars du principe que chaque nom que je rencontre dans l'expression de mes besoins correspond à un type qu'il me faudra créer et que chaque verbe que je rencontre correspond à un comportement qu'il faudra implémenter, que ce soit sous la forme d'une fonction membre ou d'une fonction libre.

    A partir de là, il devient *relativement* facile de se faire une idées des différentes relations qui existent entre les différents types que je vais devoir créer

    Bien sur, comme les besoins évoluent en permanences, il est souvent utile de repasser par cette étape d'expression claire et précise des nouveaux besoins, voire, de choses auxquelles on n'avait pas forcément pensé lors de l'itération précédente

    J'ai récemment développé cette manière de travailler lors d'une de mes interventions.

    Evidemment, mon développement se basait sur une problème particulier (le concept de pile), mais il devrait pouvoir te donner une idée de la manière dont j'ai travaillé et donc te permettre de faire de même pour ton projet
    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

  13. #13
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Une classe a sémantique de valeur s'il est possible de trouver deux instances différentes de cette classe en mémoire présentant exactement les même valeurs et pouvant être considérées comme identique (par exemple : une couleur, un point, ...)

    Ces classes sont, généralement, copiables, assignables, comparables par égalité (parfois par inégalité), constantes (la modification d'une des valeurs qui les composent occasionne l'obtention... d'une nouvelle instance de cette classe) et ne sont pas adaptées à un héritage.

    Une classe a sémantique de valeur si tu ne peux pas avoir deux instances différentes de cette classe en mémoire présentant exactement les même valeurs car certaines des valeurs utilisées permettent d'identifier chaque instance de manière unique et non ambigue (par exemple : un compte bancaire, une personne, ...).

    Ces classes ne sont pas copiables ni assignables, disposent de comportements susceptibles d'en modifier certains états, et sont généralement susceptibles d'être héritée (dans les limites du LSP, évidemment ).
    Petite faute de frape ici

  14. #14
    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 Iradrille Voir le message
    Petite faute de frape ici
    Ouppsss... Au temps pour moi... Corrigé
    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

  15. #15
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Énorme prise de conscience ! Le ciel éclaircie, les oiseaux chantes ! >> DEUX types d’objets distincts pour construire un programme bien stable !

    Je vois maintenant bien la différence entre "sémantique de valeurs et d’entités".

    Par ces contraintes, la construction en ai toute chamboulée ! Je suis repartis sur un nouveau programme bien plus simple histoire d'entrainement, y'a pas à dire, ça a d'la gueule !


    Merci énormément de m'avoir remis sur un meilleur chemin, merci encore!

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

Discussions similaires

  1. Tableau dynamique à deux dimensions
    Par David Fouejio dans le forum MFC
    Réponses: 4
    Dernier message: 05/03/2007, 10h37
  2. [HashSet] Tableau dynamique à 2 dimensions
    Par ppopov dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 21/01/2007, 17h21
  3. Réponses: 4
    Dernier message: 19/12/2006, 21h06
  4. declaration d'un tableau dynamique 2 dimensions
    Par mike600river dans le forum C++Builder
    Réponses: 4
    Dernier message: 22/05/2006, 09h53
  5. Réponses: 1
    Dernier message: 09/03/2006, 18h25

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