Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 18/12/2015, à 01:11

Lrnv

[Résolut][C++] Problèmes d'héritages et de surcharges de constructeurs

Bonjour a tous. Je commence le C++ a peine, et un peu forcé par ma fac ( je suis plutot coté scripting shell que POO d'habitude wink ), et j'ai quelques soucis d'heritage, de masquage et de demasquage sur mon constructeur de copie. Enfait j'arrive juste pas a l'utiliser plus loin.

Alors soit je l'ai coder avec les pieds et il y a une grossière erreur que je ne voit pas, soit j'ai rater un tournant, dans les deux cas j'ai besoin d'un avis exterieur big_smile

Ma classe centrale Matrice

class Matrice {
	public:
	    // On mettra ici les methodes de la classe
	    
	    
	    // Les accesseurs de la classe
	        int getM() const;
	        int getN() const;
	        void setM(int const& m);
	        void setN(int const& n);
	        double getValue(int const& i, int const& j) const;
	        void setValue(int const& i, int const& j, double const& x);

	    // Constructeurs et destructeur
	        Matrice(); // Constructeur vide
	        Matrice(int const& m, int const& n); // constructeur initialisant la matrice mais pas ses valeurs
	        Matrice(int const& m, int const& n, double const& x); // contructeur initialisant la matrice ainsi que toute ses valeurs a x
	        Matrice(Matrice const&); // constructeur par copie
	        virtual ~Matrice(); // Destructeur

        // Methode In/Out : affichage et remplissage;
            void affecter();
            void afficher();

        // Methode pour la sous-matrice, la transposée, et le prduit de kronecker
            Matrice sousMatrice(int const &i, int const &j, int const &k, int const &l) const;
            Matrice transpose() const;
	        Matrice kronecker(Matrice const& B) const;

        // Methode meme-taille, utile pour coder les surcharges d'opérateurs.
            bool memeTaille(Matrice const& A) const;
	
	    // Les opérateur racourcits : leur place est dans la classe car ce sont des méthodes.
            Matrice& operator+=(double const& x);
            Matrice& operator+=(Matrice const& A);
            Matrice& operator-=(double const& x);
            Matrice& operator-=(Matrice const& A);
            Matrice& operator*=(double const& x);

        // methodes utiles pour les calculs d'inversibilitée et d'inversion, qui sont valables pour les matrices non-carrées:
            void echanger_deux_lignes(int const &i,int const &j);
            void multiplier_ligne_par_scal(int const &i, double const& x);
            void soustr_mult_ligne1_a_ligne2(int const& i, int const &j,double const &x);


	protected:
        // On mettra ici les attribus d'un ellement de la classe
     
            int _m; // le nombre de lignes de la matrice
            int _n; // son nombre de colones
            double** contenu;
        



};


// Les surcharges d'opérateurs : ( en dehors de la classe... ) // sont marqué d'un //* ceux qui ont été retapés.
    bool operator==(Matrice const& A, Matrice const& B);
    bool operator!=(Matrice const& A, Matrice const& B);
    Matrice operator+(Matrice const& A, double const& x); //*
    Matrice operator+(Matrice const& A, Matrice const& B); //*
    Matrice operator-(Matrice const& A, double const& x); //*
    Matrice operator-(Matrice const& A, Matrice const& B); //*
    Matrice operator*(Matrice const& A, double const& x); //*
    Matrice operator*(Matrice const& A, Matrice const& B);

Avec le code des méthodes ( je vous donne que celles qui pose problème ici wink ):

// Constructeurs et destructeur
        Matrice::Matrice() // Constructeur vide
        {
        
        } 
        
        Matrice::Matrice(int const& m, int const& n) : _m(m), _n(n) // constructeur initialisant la matrice mais pas ses valeurs
        {
            contenu= (double**)malloc(_m*sizeof(double*));
            for (int i=0;i<_m;i++)
            {
                contenu[i]=(double *)malloc(_n*sizeof(double)); 
            }
        } 
        
        Matrice::Matrice(int const& m, int const& n, double const& x) : _m(m), _n(n) // contructeur initialisant la matrice ainsi que toute ses valeurs a x
        {
            contenu= (double**)malloc(_m*sizeof(double*));
            for (int i=0;i<_m;i++)
            {
                contenu[i]=(double *)malloc(_n*sizeof(double));
                for (int j=1;j<_n;j++)
                {
                    setValue(i,j,x);   
                }  
            }
        } 
        
        Matrice::Matrice(Matrice const& matrice) : _m(matrice._m), _n(matrice._n) // constructeur par copie
        {
           
           contenu= (double**)malloc(_m*sizeof(double*)); // Dans les constructeurs, on evite d'en apeller d'autres...
           for (int i=0;i<_m;i++)
            {
                contenu[i]=(double*)malloc(_n*sizeof(double));
                for (int j=0;j<_n;j++)
                {
                    contenu[i][j]=matrice.getValue(i,j); //remplissage...  
                }  
            }

        } 
        
        Matrice::~Matrice() // Destructeur de la matrice
        {
            // ici il faut free la matrice... on free d'abord les contenu[i] avent de free contenu d'un coup.
            for (int i=0;i<getM();i++)
            {
                free(contenu[i]);
            }
            free(contenu);

        };

Et ma classe héritée MatriceCarree :

class MatriceCarree:public Matrice
{
    public:
        
        // Redefinition des constructeurs :
            MatriceCarree(); // constructeur vide
            MatriceCarree( int const & n); // constructeur qui alloue et remplis avec l'identitée
            MatriceCarree( int const & n, double const & x); // constructeur qui remplis de x.
            MatriceCarree( Matrice const& mat); // constructeur par copie de matrice par carree
            virtual ~MatriceCarree();            

        // Inversibilitée, inversion :
            bool inversible() const;
            MatriceCarree inverse() const;

protected:



};

Ainsi que le coeur du problème, ses constructeurs :

// Redefinition des constructeurs :
        MatriceCarree::MatriceCarree(){} // constructeur vide
        MatriceCarree::MatriceCarree( int const & n): Matrice(n,n,0) // constructeur qui alloue et remplis avec l'identitée
        {
           for ( int i=0;i<n;i++ ) { for (int j=0;j<n;j++) {
                if ( i==j )
                {
                    setValue(i,j,1); // des 1 sur la diagonale
                }
                else
                {
                    setValue(i,j,0); // et des 0 partout ailleur
                }
           }} // ça fais bien l'identitée ;)
        }
        MatriceCarree::MatriceCarree( int const & n, double const & x): Matrice(n,n,x){} // constructeur qui remplis de x.
        
        // Redefinir le contructeur par copie permetra de faire un masquage interessant.
        MatriceCarree::MatriceCarree( Matrice const& mat) // constructeur par copie de matrice pas carree
        {
            // redefinir le constructeur par copie permetra de masquer cette operation. On pourra ainsi contruire des matricecarée via une copie de matricarrée
            // Donc, a condition que ma matrice en entrée soit carrée, je peut la copiée dan une matrice carrée. Dans le cas contraire, cela la coupera et prendra le caré minimum
            
            // calcul du minimum linge / colones
            int min=mat.getM();
            if ( min > mat.getN() ) { min=mat.getN() }

            // construction par copie de la fameuse matrice carrée.
            // elle sera donc de taille min;

            contenu= (double**)malloc(min*sizeof(double*)); // Dans les constructeurs, on evite d'en apeller d'autres...
            for (int i=0;i<min;i++)
            {
                contenu[i]=(double*)malloc(min*sizeof(double));
                for (int j=0;j<min;j++)
                {
                    contenu[i][j]=mat.getValue(i,j); //remplissage...  
                }  
            } 
        }
        
        MatriceCarree::~MatriceCarree(){} // ici pas besoin de free, le destructeur de Matrice est implicitement apeller.

Le problème : Mon constructeur par copie de MatriceCarree ne doit pas etre typé comme il faut, enfin bon, mais auand je l'appelle plus loin dans ma méthode inverse :

Matrice Kikou=Matrice(this);

Segfault.

J'ai surtout besoin de comprendre ce qui ce passe ( histoire d'apprendre, quoi). Ha oui, J'ai aussi des restriction sur les allocation, pas de new/delete a ma disposition ><"

Merci d'avence de vos réponces,

PS : N'y a t-il pas moyen d'avoir une coloration syntaxique avec le bbcode du forum ? je n'ai pas trouver..

Dernière modification par Lrnv (Le 05/01/2016, à 19:52)


Hardware : i7/8goDDR3 en desktop /// Lenovo thinkpad yoga 2 13 en laptop.
OSs : *buntu on desktop, arch / win8 on laptop
Mon Github

Hors ligne

#2 Le 18/12/2015, à 17:25

louis94

Re : [Résolut][C++] Problèmes d'héritages et de surcharges de constructeurs

Bonjour,

Ce code segfault:

Matrice a;
Matrice b(a);

Celui-ci aussi:

MatriceCarree a;
Matrice b(a);

Celui-ci pas:

Matrice a(2, 2);
Matrice b(a);

Et ça non plus:

MatriceCarree a(2);
Matrice b(a);

Ça devrait t'aider.

Louis

Hors ligne

#3 Le 02/01/2016, à 11:11

Destroyers

Re : [Résolut][C++] Problèmes d'héritages et de surcharges de constructeurs

Salut ! smile

Tu as oublié de mettre les #include nécessaires dans le code fourni (sinon ça compile pas), et il maque un point-virgule aussi, mais bon le problème n'est pas là.

En réalité, je ne sais même pas comment fonctionnent (comment on utilise) malloc et free car je ne fais que du C++... et que free et malloc sont des vestiges du C ^^ Du coup je suis désolé de ne pas t'apporter de réponse ... Je voulais simplement faire remarquer qu'il était bête de se passer des fonctionnalités (plutôt cool, pourtant) apportées par le C++, étant donné que new fait justement un malloc mais avec des vérifications supplémentaires, et de même pour free/delete. Des sécurités et une simplification d'utilisation forts sympatriques ^^

(du coup mon post sert de UP si t'as pas encore trouvé de solution ^^) Bonne chance.

Hors ligne

#4 Le 03/01/2016, à 00:08

alius

Re : [Résolut][C++] Problèmes d'héritages et de surcharges de constructeurs

Salut !

En fait je pense que l'interdiction de new et de delete n'est pas faite pour te faire utiliser des malloc ou des calloc. Je pense que l'idée était plutôt de vous forcer à utiliser des pointeurs intelligents et d'utiliser les fonction make_shared(), make_unique() ....


Alius

Hors ligne

#5 Le 05/01/2016, à 19:51

Lrnv

Re : [Résolut][C++] Problèmes d'héritages et de surcharges de constructeurs

Alors non, l'utilisation de malloc/free obligatoire, c'est juste par ce que notre chargé de td n'y connais rien, et que c'est lui qui a fais le sujet, d'après ce que j'ai compris. Le sujet en lui meme impose l'utilisation de malloc/free pour l'allocation des matrices.

j'ai bien résolut le problème, cela fonctione bien, j'en suis maintenant a l'allocation avec new/delete des objets Matrice / MatriceCarré dans un tableau de Matrice indiférenciée ( pour l'interface du logiciel ).

Du coup la on me demande d'utiliser new/Delete. je reviendrais vers vous a la fin de la semaine, j'ai trop d'autres partiels a géré en ce moment et le projet d'info peut attendre : Je suis un peu dans l'urgence. Merci en tout cas de vos réponces.

Le code ayant bien changé depuis la dernière publication, je vais marquer cela Résolu, et je re-posterais.


Hardware : i7/8goDDR3 en desktop /// Lenovo thinkpad yoga 2 13 en laptop.
OSs : *buntu on desktop, arch / win8 on laptop
Mon Github

Hors ligne