Partage
  • Partager sur Facebook
  • Partager sur Twitter

Classes imbriquées et vector de classes

Sujet résolu
    13 août 2008 à 12:13:35

    Bonjour,
    Toujours dans l'esprit de me compliquer la vie utilement à des fins pédagogiques, je me retrouve avec des classes imbriquées.

    class cVideo
    {
    	public :
    		cVideo ();
    		~cVideo ();
    
    	private :
    		AVCodecContext	*pCodecCtx;
    		AVCodec		*pCodec;
    		int		m_idFlux;
    		int		m_nombreFrames;
    		AVRational	m_dimensions;
    		AVRational	m_trueDimensions;
    		AVRational	m_aspectRatio;
    		AVRational	m_baseTemps;
    		std::string	m_codec;
    		int		m_bitRate;
    };
    
    class cAudio
    {
    	public :
    		cAudio ();
    		~cAudio ();
    
    	private :
    		AVCodecContext	*pCodecCtx;
    		AVCodec		*pCodec;
    
    		int		m_idFlux;
    		std::string	m_codec;
    		int		m_bitRate;
    		int		m_sampleRate;
    		int		m_nbCanaux;
    };
    
    class cConteneur
    {
    	public :
    		cConteneur ();
    		cConteneur (const std::string & Fichier);
    		~cConteneur ();
    		int initialise (const std::string & Fichier);
    
    		unsigned int	nbFlux (void);
    		std::string	titre (void);
    		std::string	auteur (void);
    		std::string	copyright (void);
    		std::string	commentaire (void);
    		std::string	album (void);
    		int		annee (void);
    		int		piste (void);
    		std::string	genre (void);
    		int64_t		duree (void);
    		int64_t		tailleFichier (void);
    		int		bitRate (void);
    		unsigned int	nombreChapitres (void);
    		std::string	dureeTxt (void);
    	private :
    		AVFormatContext		*pFormatCtx;
    		std::vector<cVideo *>	video;
    		std::vector<cAudio *>	audio;
    };
    


    Chaque film (cConteneur) peut avoir plusieurs flux vidéo et audio (et par la suite sous titres...), d'où l'utilisation de vectors std::vector<cVideo *> video et std::vector<cAudio *> audio.

    Pour initialiser un nouveau cVideo par exemple, est-il correct d'écrire :

    void cConteneur::setNewFluxVideo (int idFlux)
    {
    	cVideo *newFlux;
    	newFlux = new cVideo (idFlux);	// Après avoir créé le constructeur cVideo::cVideo (int), bien entendu.
    	video.push_back (newFlux);
    }
    


    Quant au destructeur de cConteneur, mon envie première serait d'écrire :
    cConteneur::~cConteneur ()
    {
    	while (!video.empty ())
    	{
    		if (video.back () != NULL)
    			delete video.back();
    		video.pop_back ();
    	}
    
    	while (!audio.empty ())
    	{
    		if (audio.back () != NULL)
    			delete audio.back();
    		audio.pop_back ();
    	}
    
    	av_close_input_file (pFormatCtx);
    }
    

    Suis-je dans le vrai ?

    N'ayant pas de debbuger (il va vraiment falloir que je réfléchisse à la question), je ne travaille guère qu'en suppositions :(
    • Partager sur Facebook
    • Partager sur Twitter
      13 août 2008 à 13:28:12

      Bonjour,

      2 conseils avant d'aller plus loin :
      - Il n'y a dans ton code aucune classe imbriquée dans une autre.
      Une classe imbriquée dans une autre c'est :
      class A
      {
        class B
        {
          // ...
        };
        // ...
      };
      

      Donc essaye de relire un peu sur le sujet pour bien fixer tes idées sur tout cela.

      - Installe gdb ou utilise le debugger de VS (enfin ça dépend de ce que tu utilises pour écrire ton code) afin de te rendre compte toi-même de ce qui cloche. Ce n'est pas difficile d'utiliser un debugger. Il y a un excellent tuto sur DDD, la version "graphique" de gdb. Il est ici : http://hiko-seijuro.developpez.com/articles/ddd/ ;)

      Bon courage
      • Partager sur Facebook
      • Partager sur Twitter
        13 août 2008 à 13:31:27

        salut, ton premier code me semble juste même si personnelement j'aurais directement fais
        void cConteneur::setNewFluxVideo (int idFlux)
        {
        	video.push_back (new cVideo (idFlux));
        }
        


        pour le 2ème ça me parait assez juste aussi même si j'aurais utiliser un itérateur pour ma part
        cConteneur::~cConteneur ()
        {
              std::vector<cVideo *>::iterator it_v;
                for (it_v=video.begin(); it_v!=vide.end(); it_v++)
                         if (*it_v != NULL) delete *it_v;
        
            //...
        
        	
        }
        


        tes vecteurs contiendront alors plein de pointeurs sur des adresses libérées et seront détruits directement (le pop_back (); ne sert à rien)
        • Partager sur Facebook
        • Partager sur Twitter
          13 août 2008 à 13:45:09

          Citation : Alp

          Bonjour,

          2 conseils avant d'aller plus loin :
          - Il n'y a dans ton code aucune classe imbriquée dans une autre.
          Une classe imbriquée dans une autre c'est :

          class A
          {
            class B
            {
              // ...
            };
            // ...
          };
          


          Donc essaye de relire un peu sur le sujet pour bien fixer tes idées sur tout cela.


          Le terme "imbriqué" n'est donc pas le bon.
          Ma définitions des classes semblent être par contre correspondre idéalement à ce que je veux faire. Une classe cConteneur peut contenir un ou plusieurs flux video et un ou plusieurs flux audio.
          Et justement, j'ai beaucoup lu et ce que je trouve éventuellement est plutôt du genre "un personnage a une arme"... moi je souhaite pouvoir en avoir plusieures (mon coté corse sans doute :lol: ).

          Citation : Alp


          - Installe gdb ou utilise le debugger de VS (enfin ça dépend de ce que tu utilises pour écrire ton code) afin de te rendre compte toi-même de ce qui cloche. Ce n'est pas difficile d'utiliser un debugger. Il y a un excellent tuto sur DDD, la version "graphique" de gdb. Il est ici : http://hiko-seijuro.developpez.com/articles/ddd/ ;)

          Bon courage


          J'utilise notepadd ++ et/ou Code::Blocks et Qt4.
          Pas de soucis de debugger sous Code::Blocks pour du C++ traditionel, mais pour Qt4, je n'ai pas trouvé. Je file regarder ton lien !


          Citation : jolrael


          pour le 2ème ça me parait assez juste aussi même si j'aurais utiliser un itérateur pour ma part


          Dans ma série Questions de newb, quel est l'intérêt d'utiliser un itérateur ?
          D'après ce que je viens de lire (en vitesse, je l'avoue), l'itérateur va permettre de parcourir les différents éléments d'un vector (entre autre), on obtiendrait le même résultat avec une boucle autour d'un vector[indice] ou vecteur.at (indice).
          Dans les 2 cas on a une boucle et les mêmes contrôles à effectuer.
          Je vais m'y plonger un petit peu en tout cas.

          Merci à vous !
          • Partager sur Facebook
          • Partager sur Twitter
            13 août 2008 à 16:25:59


            cConteneur::~cConteneur ()
            {
                std::vector<cVideo *>::iterator it_v;
                
                for( it_v = video.begin(); it_v != video.end(); ++it_v )
                    delete *it_v;
            
                //...
            }
            


            1) if( *it_v != NULL ) est inutile, la validation est déjà faite par delete ;

            2) pré incrémentation sur un itérateur (++itt ). Cela ne nécessite aucune copie contrairement à la post incrémentation. C'est aussi vrai pour tout autre type.

            3) Je suis peut-être pointilleux mais une bonne indentation et un espacement entre chaque partie de façon clair c'est mieux sur un forum. On est pas tous habitué à lire des for compactes. Et il est plus facile de relever les erreurs de frappe, ex : it_v!=vide.end(); o_O



            Pour ce que tu appels classe imbriquées, le bon concept est la composition. "Une classe A est composé d'un B" ou "A a un B"

            class B;
            
            class A
            {
                B b;
            public:
                // ...
            };
            
            // ...
            



            Petite idée polymorphique : Un FluxVideo et un FluxAudio ne sont-il pas tout les deux des Flux ?
            • Partager sur Facebook
            • Partager sur Twitter
              13 août 2008 à 16:44:55

              Complément à la remarque de Mattex : le lien (tel que défini par eNeos) entre cConteneur et les flux est une agrégation. Voir http://fr.wikipedia.org/wiki/Composition_(programmation) et http://fr.wikipedia.org/wiki/Agr%C3%A9gation_(programmation) et plus particulièrement le dernier qui présente la différence.

              Concernant le polymorphisme et les flux, je plussoie d'autant plus que c'est à des fins pédagogiques.

              edit : bug des liens
              • Partager sur Facebook
              • Partager sur Twitter
                13 août 2008 à 17:57:30

                Merci pour vos compléments d'info très instructifs ! Il s'agissait donc d'une erreur de langage, mon idée est bien de faire une agrégation.

                Pour ce qui est de la notion de polymorphisme, je vais attendre encore un peu... J'ai découvert la POO, les classes, le C++ et Qt4 la semaine dernière avec comme base de départ les tutos du site et google. J'ai déjà fort à faire et je commence à m'embrouiller à force de fureter partout. Mais je garde l'idée sous le coude ; un jour je serai fier de moi :lol:
                • Partager sur Facebook
                • Partager sur Twitter

                Classes imbriquées et vector de classes

                × 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