Partage
  • Partager sur Facebook
  • Partager sur Twitter

Tableau de structure

Initialisation Problèmatique

Sujet résolu
    20 août 2016 à 1:50:31

    Bonjour j'ai un problème et j'ai du mal comprendre ce qui se passe exactement,
    je souhaite crée une structure, et en faire un tableau,
    j'initialise les valeurs a 0, et ensuite affiche le contenu,
    pour une raison qui m'échappe les deux première valeur ne contienne pas 0,

    voici le code

    struct Segment
    {
    
        int a;
        int b;
        int c;
        vec2 A; //glm
        vec2 B; //glm 
    };
    
    int main(int argc, char *argv[])
    {
    /****/
    
      Segment segment[10];
    
      for(int i=0;i<10;i++)
      {
          segment[i].a = 0;
          segment[i].b = 0;
          segment[i].c = 0;
          segment[i].A = vec2(0,0);
          segment[i].B = vec2(0,0);
       }
    
      for(int i=0;i<10;i++)
      {
            
        cout<<i<<" "<<segment[i].a<<" "<<segment[i].b<<" "<<segment[i].c<<" "<<segment[i].A.x<<" "<<segment[i].A.y<<" "<<segment[i].B.x<<" "<<segment[i].B.y<<endl;
      }
    
    /****/
    }

    voici ce que j'obtiens 

     
    0 1133903872 1137016832 0 0 0 0 0
    1 0 0 0 0 0 0 0
    2 0 0 0 0 0 0 0
    3 0 0 0 0 0 0 0
    4 0 0 0 0 0 0 0
    5 0 0 0 0 0 0 0
    6 0 0 0 0 0 0 0
    7 0 0 0 0 0 0 0
    8 0 0 0 0 0 0 0
    9 0 0 0 0 0 0 0
    • Partager sur Facebook
    • Partager sur Twitter
      20 août 2016 à 10:22:38

      Salut,

      en voyant ton code, je ne  comprends pas pourquoi ça fait ça. Il n'y a pas de débordement visiblement.

      Tu as mis tout le code, ou tu as épuré un peu ? Peut être que tu flingues la mémoire à un endroit que tu as épuré ?

      Sinon, de manière propre, en C++ tu peux définir des constructeurs pour les structures (qui sont des classes publiques)

      Ainsi, si tu mets un constructeur qui te met a=b=c=0 et pareil pour tes vec2, tu n'as plus besoin de faire ton premier for. Le simple fait de créer ton tableau va appeler les constructeurs par défaut de tous les éléments.

      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        20 août 2016 à 11:39:46

        bonjour, Comme dit Fvirtman, il est mieux de définir un constructeur par défaut qui initialisera tes données à 0. Il apportera une meilleur garantit de ce qui se trouve dans tes variables et évitera des lignes en plus répétées inutilement à chaque création d'un objet Segment. Imagine que tu crée un segment mais malheureusement tu ne l'initialise pas, et bien dans ce cas les valeurs dans tes variables seront indéterminées et donc tu travailleras surement avec des données erronées. Pour le problème des valeurs différentes de 0, dans le code que tu as posté, n'a tu pas oublier d'écrire une instruction qui apparaît dans ton réel code ?. Pour la taille du tableau du tableau, tu peux la stocker dans une variable pour ne pas à chaque fois écrire 10. Car si un jour tu change de taille pour le tableau, tu devra copier à tout les endroits la nouvelle valeur. Comme tableau tu peux utiliser std::array qui est un tableau statique et fourni une interface simple d'utilisation: .size() pour avoir la taille du tableau.
        • Partager sur Facebook
        • Partager sur Twitter
        Etre conscient que l'on est ignorant est un grand pas vers le savoir. [Benjamin Disraeli]
          20 août 2016 à 12:07:55

          Le problème vient effectivement d'ailleurs. (j'ai testé ton code, sans avoir le soucis).

          Par contre ton code montre une mauvaise habitude dont je te conseille de te débarrasser: "using namespace".
          Tu l'as fait pour std et pour glm. On n'importe pas tout et n'importe quoi dans l'espace global de nommage.
          Et si c'est pour en plus ajouter en commentaire ce que l'espace de nommage aurait explicité, je ne vois vraiment pas l'intérêt (cf. "vec2 A; //glm")

          • Partager sur Facebook
          • Partager sur Twitter

          Si vous ne trouvez plus rien, cherchez autre chose.

            20 août 2016 à 22:01:51

            En effet j'ai mi uniquement la partie du code qui concerne la structure, car le reste du code ne l'utilisais pas encore quand j'ai poster, 
            j'ai signaler glm en commentaire pour que vous sachiez a quel  libraire vec2 appartenais, Pour l'instant je n'ai jamais rencontré de souci intégrant std et glm dans l'espace global,

             Fvirtman: je te remercie car je ne savais pas que les constructeurs étais utilisable pour les structures j'ai implémenté ça au code.
            blackProgrammeur: d'habitude j'utilise un define pour fixer les limites

            je vous mets le code du main, il n'est pas optimisé car c'est plus un programme teste qui me permet de faire quelque expérience, je compte l'optimisé par la suite.

            /*
            Auteur: François Goorman
            Titre: collision sphere
            Description:
            1 Créer une sphère et lui donner une physique
            
            2 Tenté de lui donner une interaction physique avec un segment ou un tiangle
            */
            #include <iostream>
            #include <SDL2/SDL.h>
            #include <GL/gl.h>
            #include <GL/glu.h>
            #include "sdlglutils.h"
            #include "Input.h"
            #include "Trigonometry.h"
            
            #include <glm/glm.hpp>
            #include <glm/gtx/transform.hpp>
            #include <glm/gtc/type_ptr.hpp>
            
            #define WINDOW_WIDTH 600
            #define WINDOW_HEIGHT 400
            #define TEMPS_PROGRAMME 16
            #define TRAINER 10
            #define RAYON 5
            #define GRAVITE 0.11
            #define CHUTE_MAX 16
            #define ABSORPTION 60
            #define NBR_SEGMENT 10
            
            
            using namespace std;
            using namespace glm;
            
            struct Segment
            {
            
                int a;
                int b;
                int c;
                vec2 A; //glm
                vec2 B; //glm
            
                 Segment():a(0),b(0),c(0),A(vec2(0,0)),B(vec2(0,0))
                 {
            
                 }
            };
            
            void InitVersion();
            float Trajectoir_Rebond(float angle1,float angle2);
            bool Collision_Cercle_droite(vec2 A,vec2 B,vec2 centre_cercle,float rayon); // une droit est INFINIE pas de l'imite
            bool Collision_cercle_segment(vec2 A,vec2 B,vec2 centre_cercle,float rayon);
            vec2 ProjectionI(vec2 A,vec2 B,vec2 P);//permet de connaitre le point i dune collision par apport a un segment 2D
            vec2 ProjectionI_Sphere(vec2 A,vec2 B,vec2 P,float rayon);//identique a ProjectionI en prenant en compte que c'est une cercle
            vec2 Normal_segment(vec2 A,vec2 B,vec2 P);//normal (angle hortoconal) du segment
            vec2 Calcule_Vecteur_trajectoir(vec2 v,vec2 N);
            float norme(vec2 A,vec2 B,vec2 P);
            
            int main(int argc, char *argv[])
            {
                bool continuer = true;
                Input input;
                vec2 trajectoir(6,3);
                vec2 position(0,0);
                Trigonometry tri;
                float angleDroite=180;
                float angleTrajectoir=45;
                vec2 curseur(WINDOW_WIDTH/2,WINDOW_HEIGHT-5);
                Segment segment[NBR_SEGMENT]; //PROBLEME table 0 du tableau ne veut pas signitialiser correctement
            
                //segment[0].A = vec2(290,300);
                //segment[0].B = vec2(350,360);
                segment[1].A = vec2(280,300); /*obstacle*/
                segment[1].B = vec2(350,360);
                segment[2].A = vec2(0,WINDOW_HEIGHT);
                segment[2].B = vec2(0,0);
                segment[3].A = vec2(0,0);
                segment[3].B = vec2(WINDOW_WIDTH,0);
                segment[4].A = vec2(WINDOW_WIDTH,0);
                segment[4].B = vec2(WINDOW_WIDTH,WINDOW_HEIGHT);
            	
                vec2 historique[TRAINER];
                for(int i=0;i<=TRAINER;i++)
                {
                    historique[i] = curseur;
                }
                vec2 _curseur; //cache
                vec2 chute;//vecteur de force de la boule
                vec2 pos_boule(WINDOW_WIDTH/2,WINDOW_HEIGHT-5);//vecteur de position de la boule
                Uint32 start_time,elapsed_time;
                bool gravite = true;
            
                SDL_Window *fenetre;
                SDL_Event event;
            
                SDL_GLContext contextOpenGL(0);
                InitVersion();
                fenetre = SDL_CreateWindow("Collision sphere opengl",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH,WINDOW_HEIGHT,SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL);
            
                if(!fenetre)
                {
                    cout<<"SDL_Error : " <<SDL_GetError()<<endl;
                    SDL_DestroyWindow(fenetre);
                    SDL_Quit();
                    return -1;
                }
                contextOpenGL = SDL_GL_CreateContext(fenetre);
            
                if(contextOpenGL == 0)
                {
                    cout<<"Erreur lors de l'initialisation du Context "<< SDL_GetError() <<endl;
                    SDL_DestroyWindow(fenetre);
                    SDL_Quit();
                    return -1;
                }
            
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluOrtho2D(0,WINDOW_WIDTH,0,WINDOW_HEIGHT);
            
                input.capturerPointeur(true);
            
                for(int i=0;i<NBR_SEGMENT;i++)
                {
                    cout<<i<<" "<<segment[i].a<<" "<<segment[i].b<<" "<<segment[i].c<<" "<<segment[i].A.x<<" "<<segment[i].A.y<<" "<<segment[i].B.x<<" "<<segment[i].B.y<<endl;
                }
            
                while(continuer)
                {
                    start_time = SDL_GetTicks();
            
                    input.updateEvenements();
                    SDL_PollEvent(&event);
                    if(input.terminer() == true){continuer = false;}
                    if(input.getTouches(SDL_SCANCODE_ESCAPE)){continuer = false;}
                    if(input.getTouches(SDL_SCANCODE_LEFT)){angleDroite+=0.1;}
                    if(input.getTouches(SDL_SCANCODE_RIGHT)){angleDroite-=0.1;}
                    if(input.getBoutonSouris(SDL_BUTTON_LEFT))
                    {
                        curseur = vec2(WINDOW_WIDTH/2,WINDOW_HEIGHT-5);
                        chute = vec2(0,0);
                    }
                    if(input.getBoutonSouris(SDL_BUTTON_RIGHT))
                    {
                        gravite = !gravite;
                    }
                    angleTrajectoir += input.getYWheel()/10;
            
                    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
            
                    glMatrixMode(GL_MODELVIEW);
                    glLoadIdentity();
            
                      /*DROITE COLLISION*/
                      glPushMatrix();
                       glBegin(GL_LINES);
                       glColor3ub(0,150,150);
                       for(int i=1;i<NBR_SEGMENT;i++)
                       {
                         glVertex2d(segment[i].A.x,segment[i].A.y);
                         glVertex2d(segment[i].B.x,segment[i].B.y);
                       }
                       glEnd();
                      glPopMatrix();
            
            
            
                      /*CURSEUR CERCLE*/
            
                      _curseur = curseur;
                      if(gravite)
                      {
                          if(curseur.y <-CHUTE_MAX){curseur.y = WINDOW_HEIGHT;}// si on tombe plus bas que lécran être téléporter au desus de lécrans
                          if(chute.y <CHUTE_MAX) // continuer daccéléré tant que lon a pas depasser la vitesse de chute maximal
                          {
                             chute += vec2(0,GRAVITE);
                          }
                          else{chute.y = CHUTE_MAX;}
                          curseur -= chute;
                      }
                      else
                      {
                      curseur += vec2(input.getXRel(),-input.getYRel());
                      }
            
                      glPushMatrix();
                      /*COLLISION*/
                      for(int i=1;i<NBR_SEGMENT;i++)
                      {
                        if(tri.Collision_Cercle_Segment(segment[i].A,segment[i].B,curseur + ((curseur - _curseur)/vec2(2,2)),RAYON))//permet de tester si il ya collision entre le segment A et B pour eviter de passer a travers segment
                        {
                            curseur = ProjectionI_Sphere(segment[i].A,segment[i].B,curseur,RAYON);
                            glColor3ub(255,0,0);
                            /*TESTE DE TRAJECTOIR */
                            if(gravite)
                            {
                                vec2 Normal = Normal_segment(segment[i].A,segment[i].B,curseur);
                                chute -= vec2(0,chute.y/ABSORPTION);//perte de force du a la collision
                                chute = Calcule_Vecteur_trajectoir(chute,Normal);
                            }
                        }
                        else if(tri.Collision_Cercle_Segment(segment[i].A,segment[i].B,curseur,RAYON))
                        {
                            curseur = ProjectionI_Sphere(segment[i].A,segment[i].B,curseur,RAYON);
                            glColor3ub(255,0,0);
                            /*TESTE DE TRAJECTOIR */
                            if(gravite)
                            {
                                vec2 Normal = Normal_segment(segment[i].A,segment[i].B,curseur);
                                chute -= vec2(0,chute.y/ABSORPTION);//perte de force du a la collision
                                chute = Calcule_Vecteur_trajectoir(chute,Normal);
                            }
                        }
                        else{glColor3ub(255,255,255);}
                       }
            
                       glTranslated(curseur.x,curseur.y,0);
                       glBegin(GL_LINE_LOOP);
            
            
                        for(float i=0;i<=360;i+=360/10)
                        {
                         position = tri.Projection_Vecteur_Axe(vec2(0,1),i,RAYON);
                         glVertex3d(position.x,position.y,0);
                        }
                        //glTranslated(20,20,0);
                        glEnd();
                      glPopMatrix();
            
                        for(int i=0;i<TRAINER;i++)
                        {
                            historique[i]= historique[i+1];
                        }
                          historique[TRAINER] = curseur;
            
                      /*TRAINER TRAJECTOIR CERCLE*/
                      glPushMatrix();
                       glBegin(GL_LINES);
                        glColor3ub(30,30,255);
                        for(int i=0;i<TRAINER;i++)
                        {
                            if(historique[i]!= historique[i+1])
                            {
                            glVertex2d(historique[i].x,historique[i].y);
                            glVertex2d(historique[i+1].x,historique[i+1].y);
                            }
                        }
                       glEnd();
                      glPopMatrix();
            
                    glFlush();
                    SDL_GL_SwapWindow(fenetre);
            
                    elapsed_time = SDL_GetTicks() -  start_time;
                    //cout<<TEMPS_PROGRAMME<<" - "<<elapsed_time<<" = "<<TEMPS_PROGRAMME - elapsed_time<<endl; //temps ecouler entre deux frame
                    if(elapsed_time < TEMPS_PROGRAMME)
                    {
                         SDL_Delay(TEMPS_PROGRAMME - elapsed_time);
                    }
            
                    //cout<<trajectoir.x<<" "<<trajectoir.y<<endl;
                }
                SDL_GL_DeleteContext(contextOpenGL);
                SDL_DestroyWindow(fenetre);
                SDL_Quit();
            
                return 0;
            }
            
            void InitVersion()
            {
                SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,2);
                SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,0);
                SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
                SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24);
            }
            float Trajectoir_Rebond(float angle1,float angle2) // obsolette
            {
                float angle_Perpendiculaire = angle1 + 90;//par apport au mur
                //cout<< angle1<<" + 90 = "<<angle_Perpendiculaire <<endl;
                float differance = angle_Perpendiculaire - angle2;// calcule la différence entre l'angle 2 et l'angle perpendiculaire
                //cout<< angle2<<" - "<<angle_Perpendiculaire<< " = "<<differance <<endl;
                return angle_Perpendiculaire + differance;
            }
            vec2 ProjectionI(vec2 A,vec2 B,vec2 P)
            {
                vec2 u,AC;
                u = B - A;
                AC = P - A;
                float ti = dot(u,AC)/dot(u,u);
                vec2 I;
                I = A + ti *u;
                return I;
            }
            vec2 ProjectionI_Sphere(vec2 A,vec2 B,vec2 P,float rayon)
            {
                vec2 u,AC;
                u = B - A;
                AC = P - A;
                float ti = dot(u,AC)/dot(u,u);
                vec2 I;
                I = A + ti *u;
                I += (Normal_segment(A,B,P)*vec2(rayon,rayon));//ajoute une séparation de l'épaisseur (rayon) de la sphere
                return I;
            }
            vec2 Normal_segment(vec2 A,vec2 B,vec2 P)
            {
                vec2 AC,u,N;
                u = B - A;
                AC = P - A;
                float parenthesis = u.x*AC.y-u.y*AC.x; // calcul une fois pour les deux
                N = vec2(-u.y*parenthesis,u.x*parenthesis);
                //normalisation (1)
                float norme = sqrt(N.x*N.x + N.y*N.y);
                N/=norme;
                return N;
            }
            vec2 Calcule_Vecteur_trajectoir(vec2 v,vec2 N)
            {
                vec2 v2;
                float pscal = dot(v,N);
                v2 = v-2*pscal*N;
                return v2;
            }
            



            • Partager sur Facebook
            • Partager sur Twitter
              20 août 2016 à 23:14:31

              Bonjour,

              Quelques petites remarques :

              • Découpe mieux ton code
              • les namespace ne sont pas la pour faire joli (comme ça été déjà dit plus haut). `using namespace ...;` c'est l'anti-namespace (surtout pour des namespaces dont le nom est de 3 lettres...).
              • les macros c'est pas bien (à part quand on parle de poisson), utilises des constantes (`const ou mieux constexpr` en c++11 et +)
              • fais de surcouches RAII pour les bibliothèques C (SDL et autres)
              • utilises un constructeur avec des paramètres pour `Segment`

              Ton problème à été résolu avec l'introduction des constructeurs pour `Segment` (normalement le constructeur doit résoudre ton problème) ?

              • Partager sur Facebook
              • Partager sur Twitter
                20 août 2016 à 23:30:04

                boucle avec i<=TRAINER -> dépassement de tableau. N'importe quel analyseur dynamique le détecte, notamment ceux intégrés au compilateur et activable avec -fsanitize=address ou -fsanitize=undefined.

                Je n'ai pas été plus loin, mais déjà:

                • N'utilise pas des defines pour définir des constantes, mais fait le à travers de vrai variable constante (constexpr).
                • On ne construit pas objet par l'intermédiaire d'un objet temporaire du même type A(vec2(0,0)) -> A(0,0). Même si je pense que le constructeur par de défaut initialisation suffit A{}
                • C'est pérrave de faire un constructeur comme ça, autant initialiser les membres au moment de leur déclaration. struct segment { vec2 A{}; ... };. En plus le virer permet de construire l'objet avec d'autre valeur.
                • Il y a le type std::size_t pour les tailles et les indices de tabeau.
                • les boucles range-for sont nettement plus simples qu'utiliser des indices et des tailles.
                • std::array est nettement plus sûr qu'un tableau C-style. En plus une assertion aurait fait crasher le prog avec la ligne qui fait l'overflow.
                • L'initialisation de tableau en plusieurs étapes, c'est moche. `Segment segment[NBR_SEGMENT]{{0,0,0,{290,300},{350,360}}, etc}; /obstacle/
                • Ne déclare pas les variables au début de fonction, mais au moment de leur utilisation. Au passage le main est trop grand.
                • Partager sur Facebook
                • Partager sur Twitter
                  21 août 2016 à 2:16:05

                  nefas: le constructeur pour segment na pas résolut mon problème ,
                  Pourquoi ne faut t'il pas utiliser de define et plutôt des variable constante?

                  jo_link_noir: pour la construction du vec2 si je l'initialise en fessant "vec2 A(0,0)" ça marche si je fait comme tu a dit ça ne fonctionne pas la librarie glm le permet pas sinon je l'aurait fait bien avant crois moi 
                  le main est trop long oui tu a raison, j'ai bien expliquer que c'étais un programme teste, je me suis lancer avec un objectif mais aucune idée de comment faire donc y'a eu beaucoup de tatonement

                  EDIT: jo_link_noir Tu avais raison pour i <=TRAINER j'ai effectivement mi un = (par accident) et apparemment cet case débordait sur l'adresse de la structure sa ne serrait pas arriver si javais utiliser un tableau dynamique,
                  le problème est résolut merci a tous. 

                  -
                  Edité par la colombe noir 21 août 2016 à 5:35:10

                  • Partager sur Facebook
                  • Partager sur Twitter
                    21 août 2016 à 12:34:59

                    la colombe noir a écrit:

                    Pourquoi ne faut t'il pas utiliser de define et plutôt des variable constante?

                    Parce que les define ne sont pas typés, mais les variables constantes si
                    De plus les macros n'ont pas de scope, et ne peuvent pas être mises dans des namespaces (polluant ainsi l'espace de nommage global).

                    la colombe noir a écrit:

                    jo_link_noir: pour la construction du vec2 si je l'initialise en fessant "vec2 A(0,0)" ça marche si je fait comme tu a dit ça ne fonctionne pas la librarie glm le permet pas sinon je l'aurait fait bien avant crois moi 

                    Le constructeur par défaut des glm::vec2 met bien x et y à 0.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Si vous ne trouvez plus rien, cherchez autre chose.

                      21 août 2016 à 18:28:38

                      ha oui effectivement il les mets à 0, c'est mon habitude de toujours préciser a l'initialisation, je pensais que tu parlais de l'operateur =, qui lui ne prend qu'une variable de type vec2.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        22 août 2016 à 23:38:47

                        bonjour,

                        ce code :

                            vec2 historique[TRAINER];
                            for(int i=0;i<=TRAINER;i++)
                            {
                                historique[i] = curseur;
                            }

                        a la particularité d'écraser la variable déclarée avant donc ici le début de Segment segment[NBR_SEGMENT];

                        • Partager sur Facebook
                        • Partager sur Twitter

                        En recherche d'emploi.

                          23 août 2016 à 8:25:22

                          @Dalfab : pas nécessairement, c'est ça qui est "agréable" avec les UB.

                          @la colombe noir : ton code n'est pas du tout robuste aux exceptions, les éléments de la SDL étant désalloués manuellement, crée une capsule RAII pour ces machins.

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                            24 août 2016 à 3:12:17

                            @Dalfab: je l'ai remarquer y'a quelque temps c'est corriger depuis.

                            @Ksass`Peuk: je compte refondre le code et mettre le tout dans un ou plusieurs objets.

                            -
                            Edité par la colombe noir 24 août 2016 à 3:13:43

                            • Partager sur Facebook
                            • Partager sur Twitter
                              24 août 2016 à 9:56:36

                              Pour les objets de la SDL, je me suis fait une petite classe RAII pour pallier aux eventuels leaks de ressources, en cas d'exception:

                              template< typename T >
                              struct SdlPointer
                              {
                              	using dtorFunc = void( * )( T * );
                              
                              	SdlPointer( SdlPointer< T > const & ) = delete;
                              	SdlPointer & operator=( SdlPointer< T > const & ) = delete;
                              	SdlPointer( SdlPointer< T > && ) = default;
                              	SdlPointer & operator=( SdlPointer< T > && ) = default;
                              
                              	inline SdlPointer( T * pointer, dtorFunc dtor )
                              		: m_pointer( pointer )
                              		, m_dtor( dtor )
                              	{
                              	}
                              
                              	inline ~SdlPointer()
                              	{
                              		( *m_dtor )( m_pointer );
                              	}
                              
                              	inline T * operator->()const
                              	{
                              		return m_pointer;
                              	}
                              
                              	inline operator T*()const
                              	{
                              		return m_pointer;
                              	}
                              
                              private:
                              	T * m_pointer;
                              	dtorFunc m_dtor;
                              };


                              Et un petit cas d'utilisation:

                              SdlPointer< SDL_Surface > image( IMG_Load( filePath.c_str() ), SDL_FreeSurface );



                              -
                              Edité par dragonjoker 24 août 2016 à 9:59:27

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Si vous ne trouvez plus rien, cherchez autre chose.

                                24 août 2016 à 11:14:47

                                Intéressante classe ! Et en passant le pointeur de fonction vers la fonction qui free, c'est bien souple.

                                Par contre, est ce que tu gères l'éventuelle recopie ? Ou alors tu l'interdis ?

                                • Partager sur Facebook
                                • Partager sur Twitter

                                Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                                  24 août 2016 à 11:21:09

                                  Fvirtman a écrit:

                                  Par contre, est ce que tu gères l'éventuelle recopie ? Ou alors tu l'interdis ?

                                  C'est dans le code ^^ .

                                  @dragonjoker : ce serait peut être pas mal que le deleter fasse partie intégrante du type vu qu'il n'y a priori qu'un deleter par ressource si je me souviens bien. Les "inline" ne sont pas nécessaires, ce sont des fonctions membres directement définie dans la classe : elles sont implictement inline.

                                  -
                                  Edité par Ksass`Peuk 24 août 2016 à 11:21:54

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                                    24 août 2016 à 11:27:25

                                    Ksass`Peuk a écrit:

                                    @dragonjoker: ce serait peut être pas mal que le deleter fasse partie intégrante du type vu qu'il n'y a priori qu'un deleter par ressource si je me souviens bien. Les "inline" ne sont pas nécessaires, ce sont des fonctions membres directement définie dans la classe : elles sont implictement inline.

                                    -
                                    Edité par Ksass`Peuk il y a moins de 30s


                                    Oué, pour les inline, c'est une habitude que j'ai de toujours le spécifier quand je le souhaite (même si ce n'est pas nécessaire, i.e. le cas présent).
                                    Par contre, comment tu verrais le deleter en partie intégrante du type? Et quel serait l'intérêt?

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Si vous ne trouvez plus rien, cherchez autre chose.

                                      24 août 2016 à 11:46:03

                                      dragonjoker a écrit:

                                      (1) Par contre, comment tu verrais le deleter en partie intégrante du type? (2) Et quel serait l'intérêt?

                                      (1)

                                      struct Foo{};
                                      Foo* alloc_foo(){ return new Foo(); }
                                      void dealloc_foo(Foo* f){ delete f; }
                                      
                                      struct Bar{};
                                      Bar* alloc_bar(){ return new Bar(); }
                                      void dealloc_bar(Bar* b){ delete b; }
                                      
                                      template<class T, std::add_pointer_t<void(T*)> function>
                                      struct ptr{
                                        ptr(T* t) : t(t) {}
                                        ~ptr(){ function(t); };
                                        T* t;
                                      };
                                      
                                      
                                      int main(int argc, char** argv){
                                        ptr<Foo, dealloc_foo> p1(alloc_foo());
                                        ptr<Bar, dealloc_bar> p2(alloc_bar());
                                      }

                                      (2) Pas de pointeur stocké pour le deleter donc moins d'espace occupé sur la pile et pas d'indirection au moment de l'appel de deleter puisque c'est dans le type.

                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                                        24 août 2016 à 12:01:19

                                        Intéressant effectivement, bon je peux pas l'inclure à ma (vraie) classe (qui est censée fonctionner avec GCC 3.4 ^^') mais pour l'exemple, et pour plus tard, c'est bon à savoir.

                                        EDIT:

                                        En tout cas pas sous cette form, mais sinon ça doit quand même pouvoir se faire, faut juste que j'y réfléchisse.

                                        -
                                        Edité par dragonjoker 24 août 2016 à 12:04:08

                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Si vous ne trouvez plus rien, cherchez autre chose.

                                          24 août 2016 à 12:33:03

                                          template<class T, void (* function) (T*)>
                                          struct ptr{
                                            ptr(T* t) : t(t) {}
                                            ~ptr(){ function(t); };
                                            T* t;
                                          };
                                          
                                          
                                          int main(int argc, char** argv){
                                            ptr<Foo, dealloc_foo> p1(alloc_foo());
                                            ptr<Bar, dealloc_bar> p2(alloc_bar());
                                          }

                                          ça compile en C++98. A voir si GCC le mange.

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                                            24 août 2016 à 13:38:49

                                            Pas besoin de constructeur pour initialiser les membres.

                                            struct Segment
                                            {
                                             
                                                int a{0};
                                                int b{0};
                                                int c{0};
                                                vec2 A; //glm
                                                vec2 B; //glm
                                            };



                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            git is great because Linus did it, mercurial is better because he didn't.

                                              24 août 2016 à 14:03:44

                                              Pour le deleter des objets SDL_, je verrais bien une résolution automatique en fonction du type. À la manière d'une spécialisation de std::default_delete pour unique_ptr.

                                              template<class T, void (* function) (T*) = sdl_deallocater<T>::value>
                                              class ptr;
                                              
                                              template<> struct sdl_deallocater_impl<SDL_Surface>
                                              { static const void (* value) (T*) = SDL_FreeSurface; };
                                              
                                              template<class T> struct sdl_deallocater : sdl_deallocater_impl<T> {};
                                              template<class T> struct sdl_deallocater<const T> : sdl_deallocater_impl<T> {};

                                              Et idem pour l'allocation en fait, histoire de faire make_sdl<Sdl_Surface>(params...)

                                              -
                                              Edité par jo_link_noir 24 août 2016 à 14:06:57

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                24 août 2016 à 14:39:16

                                                Oué, pour l'allocation, en C++11 ça peut être bien intéressant. (Avec des surcharges, en C++98 aussi). Je crois que je vais jouer à ça ce soir.
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                Si vous ne trouvez plus rien, cherchez autre chose.

                                                  24 août 2016 à 18:10:01

                                                  Salut,

                                                  dragonjoker a écrit:

                                                  Pour les objets de la SDL, je me suis fait une petite classe RAII pour pallier aux eventuels leaks de ressources, en cas d'exception:

                                                  Tu pourrais tout aussi bien utiliser std::unique_ptr en fournissant le deleter gracieusement fourni par jo_link_noir :)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    24 août 2016 à 18:39:34

                                                    GCC 3.4

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter

                                                    Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                                                      25 août 2016 à 7:46:47

                                                      Ah effectivement j'ai manqué ce point. Ça pourra toujours servir à d'autres ^^
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      Tableau de structure

                                                      × 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.
                                                      • Editeur
                                                      • Markdown