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 :

surcharge de l'operateur *


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 40
    Par défaut surcharge de l'operateur *
    bonsoir,
    je suis un débutant dans le langue C++.J'ai implémenté cette classe
    mon problème est que lors de l'utilisation de l'opérateur * qui est surcharger
    le programme plante.
    S'il vous plait quelqu'un peut il m'indiquer où le problème.
    Voici le code de l'interface du classe
    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
     
    #include<iostream>
    using namespace std;
    class registre
    {
    	int *m_tab,m_taille;
    public:
    	registre(int =8);
    	registre(const registre &);
    	~registre();
      	registre &operator*(registre);
    	registre &operator+(registre);
    	registre &operator<(int);
    	registre &operator>(int);
    	registre &operator=(const registre &);
    	friend ostream &operator<<(ostream &,registre);
    	friend istream &operator>>(istream &,registre &);
    	void affiche();
    	void remplir();
     
     
    };
    Voici l'implémentation des méthodes
    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    #include "registre.h"
    registre::registre(int taille):m_taille(taille)
    {
    	m_tab = new int[m_taille];
     
    }
    registre::~registre()
    {
    	delete []m_tab;
    }
    registre::registre(const registre &r)
    {
    	m_taille =r.m_taille;
    	m_tab = new int[m_taille];
        for(int i=0;i<m_taille;i++)
    		m_tab[i]=r.m_tab[i];
     
    }
     
     
     
     
    void registre::affiche()
    {
    		for(int i=0;i<m_taille;i++)
    			cout<<"\t"<<m_tab[i];
    		cout<<endl;
    }
    void registre::remplir()
    {
    	for(int i=0;i<m_taille;i++)
    	{
     
    			cout<<"entrer 0 ou 1";
    			cin>>m_tab[i];
     
    	}
    	cout<<endl;
     
    }
     
    registre &registre::operator=(const registre& r)
    {
    	if(this!=&r)
    	{
    		delete []m_tab;
    		m_taille=r.m_taille;
    		m_tab =new int [m_taille];
    		for(int i=0;i<m_taille;i++)
    			m_tab[i]=r.m_tab[i];
    	}
    	return *this;
    }
     
    registre &registre::operator *(registre r)
    {
    	registre f;
    	if(m_taille<r.m_taille)
    	{
    		f.m_taille=r.m_taille;
    		for(int i=0;i<m_taille;i++)
    			f.m_tab[i]=m_tab[i]*r.m_tab[i];
    		for(int i=m_taille;i<r.m_taille;i++)
    			f.m_tab[i]=0;
    	}
    	else if(m_taille>=r.m_taille)
    	{
    		f.m_taille=m_taille;
    		for(int i=0;i<r.m_taille;i++)
    			f.m_tab[i]=m_tab[i]*r.m_tab[i];
    		for(int i=r.m_taille;i<m_taille;i++)
    			f.m_tab[i]=0;
    	}
    	return f;
    }
    remarque
    j'ai juste implémenter le constructeur, le destructeur,le constructeur par copier et la méthode de surcharge de l'opérateur *.
    Et en fin voici main du programme.
    j'utilise visual studio 2008.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include "registre.h"
    void main()
    {
    	registre r(2),g(3),f;
    	r.remplir();
    	g.remplir();
    	f=r*g;
    	r.affiche();
    	g.affiche();
    	f.affiche();
     
     
    }
    je vous remercie d'avance pour votre aide.

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Déjà, les opérateur +, -, * et /, s'il sont définis devraient renvoyer l'objet par valeur et non par référence...

    En effet, l'idée générale est que, lorsque tu écris t1*t2, tu obtiens un nouvel objet, qui est différent de t1 et de t2

    Par contre, la version permettant l'assignation avec ces opérateurs ( +=, -=,*= et /=) peut effectivement renvoyer une référence car il s'agit de renvoyer l'objet d'origine qui aura été modifié

    Le fait que cet opérateur renvoie un objet par référence est le premier point qui pose problème:

    l'objet qui contient le résultat (f dans le code) est créé statiquement dans la fonction (on dit "créé sur la pile"), et, comme tous les objets créés de cette manière, il est détruit lorsque l'on quitte la portée dans laquelle il est déclaré (autrement dit, ici, quand on quitte la fonction dans laquelle il est créé)...

    Au final, ta fonction renvoie donc une référence sur un objet... qui n'existe plus (et pour lequel le destructeur a été implicitement appelé lorsque l'on a atteint l'accolade fermante de la fonction).

    Toute tentative d'accéder au contenu de cette référence ne peut donc se traduire que par un comportement indéterminé (qui est le plus souvent synonyme de plantage de l'application)

    Ce problème mis à part, je constate que
    • tu utilise le constructeur par défaut lors de la déclaration de f... cela implique que f.m_taille est initialisé à la valeur par défaut (8)
    • tu vérifie la taille de l'opérande de gauche et celle de l'opérande de droite, mais pas celle de l'objet qui devra contenir le résultat

    Dans l'exemple que tu présente, tu as une chance: les tailles respectives de r (2) et de g (3) sont inférieures à la taille de f (8 par défaut), mais...

    Si, un jour, tu venais à déclarer l'équivalent de r et de g comme ayant tous les deux des tailles supérieures à celle de f, tu te trouverais dans une situation scabreuse source d'erreur de segmentation parce que tu essayerais de faire rentrer, par exemple, 9 ou 10 éléments (ou plus) dans quelque chose qui ne peut en contenir... que 8 (ou moins)

    Il faudrait donc intégrer dans ta logique de veiller à ce que l'objet de résultat dispose au minimum du nombre de cases suffisante pour pouvoir représenter l'ensemble des éléments de l'opérande le plus grand

    Ceci dit, il y a dans ton code quelques problèmes qui justifient des conseils particuliers...

    Les opérateurs < et > signifient respectivement "est plus petit que" et "est plus grand que"...

    En toute logique, leur valeur de retour est donc un booléen (vrai ou faux),et, si l'on peut envisager le fait qu'ils prennent un entier comme argument, on s'attend généralement à ce qu'ils permettent de comparer deux objets de types identiques...

    Pour ton opérateur d'affectation, il est généralement conseillé d'utiliser l'idiome dit du "copy and swap" (la copie et l'échange des données), de manière à s'assurer que les différentes ressources seront correctement libérées en temps utiles.

    Après tout, tu dispose d'un constructeur par copie et d'un destructeur qui font parfaitement le boulot que l'on attend d'eux... il est donc possible d'utiliser le fait qu'une variable locale déclarée sur la pile est détruite lorsque l'on quitte la portée dans laquelle elle est déclarée à notre avantage

    Ainsi, ton opérateur d'affectation pourrait prendre une forme 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
    registre &registre::operator=(const registre& r)
    {
        /* utilisons le constructeur par copie pour avoir un objet local 
         * identique à l'argument passé
         */
        registre temp(r);
        /* échangeons les membre de temp et  de  l'objet en cours */
        std::swap(m_tab,temp.m_tab);
        std::swap(m_taille, temp.m_taille);
        /* nous aurions pu le faire manuellement sous une forme proche de
         * m_tab^temp.m_tab;
         * temp.m_tab^m_tab;
         * m_tab^temp_m_tab;
         * m_taille^temp.m_taille;
         * temp.m_taille^m_taille;
         * m_taille^temp.m_taille;
         * mais comme le standard  nous permet d'échanger des membres
         * en une seule ligne, pourquoi s'en priver ???
         */
        /* renvoyons notre objet courent */
        return  *this;
    } // et laissons  le destructeur  libérer correctement les ressources de
      // l'objet temporaire
    }
    Et ceci m'amène tout naturellement à une dernière remarque (mais au combien importante)...

    Tu l'aura remarqué sans que je ne le dise, l'utilisation de pointeurs et de l'allocation dynamique de la mémoire sont, très clairement, source de problèmes sans noms...

    D'abord, parce qu'elles t'obligent à redéfinir une série de fonctions (le constructeur par copie, l'opérateur d'affectation et le destructeurs, pour ne pas les nommer) pour lesquelles tu aurais très bien pu faire confiance au compilateur pour les implémenter, si tu n'avait pas utilisé l'allocation dynamique...

    Ensuite, parce que l'allocation dynamique de la mémoire revient à décider de prendre toi-même la responsabilité de déterminer quand l'objet doit être détruit et qu'il est donc très facile, si tu n'es pas attentif, d'en arriver à des situations dans lesquelles tu occasionnera soit des fuites mémoire (memory leaks), soit une double libération de la mémoire (les deux cas étant tout aussi catastrophiques l'un que l'autre).

    Or, il se fait que le C++, bien que descendant tout droit du C, fournit une série de classes permettant de manipuler les collections "classiques" d'objets (tableaux contigus, piles, files, listes, arbres binaires et bien d'autres) de manière tout à fait transparente et bien plus sécurisante pour l'utilisateur que tout ce qu'il pourrait vouloir faire par lui-même.

    Le conseil que l'on martèle donc à longueur de temps est de préférer en toute circonstances les solutions propres C++ à toute solution issue du C équivalente.

    Dans ton cas, la solution propre au C++ que je te conseillerais d'utiliser est la classe vector, disponible dans l'espace de noms std par simple inclusion du fichier d'en-tête <vector>.

    Cette classe présente en effet tous les avantages d'un tableau d'éléments dynamique, tout en rajoutant les faits
    • qu'elle connait le nombre d'éléments qu'elle contient
    • qu'elle ne nécessite aucune allocation dynamique de la part de son utilisateur
    • qu'elle respecte le RAII (Ressource Acquisition Is Initialisation)
    • qu'elle fournit même en cas de besoin une fonction membre permettant de te prévenir (en lançant une exception) si, d'aventure, tu venais à tenter d'accéder à un indice hors limite (au 9 eme élément d'un tableau qui n'en contient que 8, par exemple)
    Le fait d'utiliser cette classe en remplacement de tes membres m_tab et m_taille te permettrait, entre autre:
    • de faire confiance au constructeur par copie, à l'opérateur d'assignation et au destructeur implémenté par défaut (comprend: si tu ne les déclare pas explicitement) par le compilateur
    • de gérer plus facilement n'importe quel nombre d'objet (ajout avec push_front ou push_back, insertion avec insert, suppression avec erase, vidange avec clear, ...)
    • de pouvoir connaitre en permanence le nombre d'éléments constenus(avec size)
    • d'accéder aux différents aux différents éléments avec les crochets "[]" (sans vérification d'index)
    • d'accéder aux différents éléments en assurant une vérification de la validité de l'index (avec at)
    • de faire tout cela de manière tout à fait "transparente" pour toi
    • j'en passe, et de meilleures
    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

  3. #3
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 40
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut,

    Déjà, les opérateur +, -, * et /, s'il sont définis devraient renvoyer l'objet par valeur et non par référence...

    En effet, l'idée générale est que, lorsque tu écris t1*t2, tu obtiens un nouvel objet, qui est différent de t1 et de t2

    Par contre, la version permettant l'assignation avec ces opérateurs ( +=, -=,*= et /=) peut effectivement renvoyer une référence car il s'agit de renvoyer l'objet d'origine qui aura été modifié

    Le fait que cet opérateur renvoie un objet par référence est le premier point qui pose problème:

    l'objet qui contient le résultat (f dans le code) est créé statiquement dans la fonction (on dit "créé sur la pile"), et, comme tous les objets créés de cette manière, il est détruit lorsque l'on quitte la portée dans laquelle il est déclaré (autrement dit, ici, quand on quitte la fonction dans laquelle il est créé)...

    Au final, ta fonction renvoie donc une référence sur un objet... qui n'existe plus (et pour lequel le destructeur a été implicitement appelé lorsque l'on a atteint l'accolade fermante de la fonction).

    Toute tentative d'accéder au contenu de cette référence ne peut donc se traduire que par un comportement indéterminé (qui est le plus souvent synonyme de plantage de l'application)

    Ce problème mis à part, je constate que
    • tu utilise le constructeur par défaut lors de la déclaration de f... cela implique que f.m_taille est initialisé à la valeur par défaut (8)
    • tu vérifie la taille de l'opérande de gauche et celle de l'opérande de droite, mais pas celle de l'objet qui devra contenir le résultat

    Dans l'exemple que tu présente, tu as une chance: les tailles respectives de r (2) et de g (3) sont inférieures à la taille de f (8 par défaut), mais...

    Si, un jour, tu venais à déclarer l'équivalent de r et de g comme ayant tous les deux des tailles supérieures à celle de f, tu te trouverais dans une situation scabreuse source d'erreur de segmentation parce que tu essayerais de faire rentrer, par exemple, 9 ou 10 éléments (ou plus) dans quelque chose qui ne peut en contenir... que 8 (ou moins)

    Il faudrait donc intégrer dans ta logique de veiller à ce que l'objet de résultat dispose au minimum du nombre de cases suffisante pour pouvoir représenter l'ensemble des éléments de l'opérande le plus grand

    Ceci dit, il y a dans ton code quelques problèmes qui justifient des conseils particuliers...

    Les opérateurs < et > signifient respectivement "est plus petit que" et "est plus grand que"...

    En toute logique, leur valeur de retour est donc un booléen (vrai ou faux),et, si l'on peut envisager le fait qu'ils prennent un entier comme argument, on s'attend généralement à ce qu'ils permettent de comparer deux objets de types identiques...

    Pour ton opérateur d'affectation, il est généralement conseillé d'utiliser l'idiome dit du "copy and swap" (la copie et l'échange des données), de manière à s'assurer que les différentes ressources seront correctement libérées en temps utiles.

    Après tout, tu dispose d'un constructeur par copie et d'un destructeur qui font parfaitement le boulot que l'on attend d'eux... il est donc possible d'utiliser le fait qu'une variable locale déclarée sur la pile est détruite lorsque l'on quitte la portée dans laquelle elle est déclarée à notre avantage

    Ainsi, ton opérateur d'affectation pourrait prendre une forme 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
    registre &registre::operator=(const registre& r)
    {
        /* utilisons le constructeur par copie pour avoir un objet local 
         * identique à l'argument passé
         */
        registre temp(r);
        /* échangeons les membre de temp et  de  l'objet en cours */
        std::swap(m_tab,temp.m_tab);
        std::swap(m_taille, temp.m_taille);
        /* nous aurions pu le faire manuellement sous une forme proche de
         * m_tab^temp.m_tab;
         * temp.m_tab^m_tab;
         * m_tab^temp_m_tab;
         * m_taille^temp.m_taille;
         * temp.m_taille^m_taille;
         * m_taille^temp.m_taille;
         * mais comme le standard  nous permet d'échanger des membres
         * en une seule ligne, pourquoi s'en priver ???
         */
        /* renvoyons notre objet courent */
        return  *this;
    } // et laissons  le destructeur  libérer correctement les ressources de
      // l'objet temporaire
    }
    Et ceci m'amène tout naturellement à une dernière remarque (mais au combien importante)...

    Tu l'aura remarqué sans que je ne le dise, l'utilisation de pointeurs et de l'allocation dynamique de la mémoire sont, très clairement, source de problèmes sans noms...

    D'abord, parce qu'elles t'obligent à redéfinir une série de fonctions (le constructeur par copie, l'opérateur d'affectation et le destructeurs, pour ne pas les nommer) pour lesquelles tu aurais très bien pu faire confiance au compilateur pour les implémenter, si tu n'avait pas utilisé l'allocation dynamique...

    Ensuite, parce que l'allocation dynamique de la mémoire revient à décider de prendre toi-même la responsabilité de déterminer quand l'objet doit être détruit et qu'il est donc très facile, si tu n'es pas attentif, d'en arriver à des situations dans lesquelles tu occasionnera soit des fuites mémoire (memory leaks), soit une double libération de la mémoire (les deux cas étant tout aussi catastrophiques l'un que l'autre).

    Or, il se fait que le C++, bien que descendant tout droit du C, fournit une série de classes permettant de manipuler les collections "classiques" d'objets (tableaux contigus, piles, files, listes, arbres binaires et bien d'autres) de manière tout à fait transparente et bien plus sécurisante pour l'utilisateur que tout ce qu'il pourrait vouloir faire par lui-même.

    Le conseil que l'on martèle donc à longueur de temps est de préférer en toute circonstances les solutions propres C++ à toute solution issue du C équivalente.

    Dans ton cas, la solution propre au C++ que je te conseillerais d'utiliser est la classe vector, disponible dans l'espace de noms std par simple inclusion du fichier d'en-tête <vector>.

    Cette classe présente en effet tous les avantages d'un tableau d'éléments dynamique, tout en rajoutant les faits
    • qu'elle connait le nombre d'éléments qu'elle contient
    • qu'elle ne nécessite aucune allocation dynamique de la part de son utilisateur
    • qu'elle respecte le RAII (Ressource Acquisition Is Initialisation)
    • qu'elle fournit même en cas de besoin une fonction membre permettant de te prévenir (en lançant une exception) si, d'aventure, tu venais à tenter d'accéder à un indice hors limite (au 9 eme élément d'un tableau qui n'en contient que 8, par exemple)
    Le fait d'utiliser cette classe en remplacement de tes membres m_tab et m_taille te permettrait, entre autre:
    • de faire confiance au constructeur par copie, à l'opérateur d'assignation et au destructeur implémenté par défaut (comprend: si tu ne les déclare pas explicitement) par le compilateur
    • de gérer plus facilement n'importe quel nombre d'objet (ajout avec push_front ou push_back, insertion avec insert, suppression avec erase, vidange avec clear, ...)
    • de pouvoir connaitre en permanence le nombre d'éléments constenus(avec size)
    • d'accéder aux différents aux différents éléments avec les crochets "[]" (sans vérification d'index)
    • d'accéder aux différents éléments en assurant une vérification de la validité de l'index (avec at)
    • de faire tout cela de manière tout à fait "transparente" pour toi
    • j'en passe, et de meilleures
    MERCI POUR VOS CONSEILLES.
    POUR LES OPÉRATEUR < ET > SONT DÉCLARER POUR FAIRE LES OPÉRATIONS DE DÉCALAGE DES VALEURS DE m_tab VERS LE DROITE OU VERS LA GAUCHE
    ET NON PAS POUR LA COMPARAISON JE M EXCUSE POUR NE PAS EXPLIQUER ÇA AU DÉBUT .
    POUR LE RETOUR PAR RÉFÉRENCE DE L'OPÉRATEUR * ,+
    C'EST POUR RÉSOUDRE CE PROBLÈME
    SI J'ÉCRIS ÇA:
    R*F*T AVEC R,T ET F SONT DES OBJETS DE TYPE REGISTRE DONC SI L'OPÉRATEUR * NE RETOURNE PAS UNE RÉFÉRENCE ALORS CETTE ÉCRITURE SERA INVALIDE.
    POUR L'ALLOCATION DYNAMIQUE DE MÉMOIRE , C'EST VRAI QUE C'EST UN SOURCE DE BEAUCOUP DE PROBLÈME MAIS COMME JE DÉBUTE EN C++
    LES MÉTHODES QUE VOUS VOYEZ EN CE PROGRAMME C'EST TOUS QUE
    JE SAIS POUR LE MOMENT.
    POUR CE PROBLÈME
    Si, un jour, tu venais à déclarer l'équivalent de r et de g comme ayant tous les deux des tailles supérieures à celle de f, tu te trouverais dans une situation scabreuse source d'erreur de segmentation parce que tu essayerais de faire rentrer, par exemple, 9 ou 10 éléments (ou plus) dans quelque chose qui ne peut en contenir... que 8 (ou moins)
    JE CROIS QUE CETTE LIGNE RESOUDRE LE PROBLEME
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    f.m_taille=r.m_taille;
    ET CE LIGNE LA
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    f.m_taille=m_taille;
    l'objet qui contient le résultat (f dans le code) est créé statiquement dans la fonction (on dit "créé sur la pile"), et, comme tous les objets créés de cette manière, il est détruit lorsque l'on quitte la portée dans laquelle il est déclaré (autrement dit, ici, quand on quitte la fonction dans laquelle il est créé)...

    Au final, ta fonction renvoie donc une référence sur un objet... qui n'existe plus (et pour lequel le destructeur a été implicitement appelé lorsque l'on a atteint l'accolade fermante de la fonction).
    ENFIN S.V.P EST QUE VOUS POUVEZ M'INDIQUER COMMENT JE PEUX RÉCUPÉRÉ LE RÉSULTAT DE L'OPÉRATEUR * CORRECTEMENT

    MERCI D'AVANCE POUR VOUS

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    [QUOTE=ka123tn;4414166]MERCI POUR VOS CONSEILLES.
    POUR LES OPÉRATEUR < ET > SONT DÉCLARER POUR FAIRE LES OPÉRATIONS DE DÉCALAGE DES VALEURS DE m_tab VERS LE DROITE OU VERS LA GAUCHE
    ET NON PAS POUR LA COMPARAISON JE M EXCUSE POUR NE PAS EXPLIQUER ÇA AU DÉBUT .[/CODE]Typiquement, les opérateurs de décalage de bit sont << et >>...

    Il est toujours mauvais de changer l'utilisation que l'on peut avoir d'un opérateur

    POUR LE RETOUR PAR RÉFÉRENCE DE L'OPÉRATEUR * ,+
    C'EST POUR RÉSOUDRE CE PROBLÈME
    SI J'ÉCRIS ÇA:
    R*F*T AVEC R,T ET F SONT DES OBJETS DE TYPE REGISTRE DONC SI L'OPÉRATEUR * NE RETOURNE PAS UNE RÉFÉRENCE ALORS CETTE ÉCRITURE SERA INVALIDE.
    Ce ne sera absolument pas invalide, étant donné que R*F*T correspond en réalité à (R*F)*T...

    Il y aura donc création d'un premier objet( temporaire) pour calculer R*F, suivie de la création d'un deuxième objet calculant le résultat de la multiplication du premier objet par T...

    Et c'est ce que tu ferais toi-même naturellement
    POUR L'ALLOCATION DYNAMIQUE DE MÉMOIRE , C'EST VRAI QUE C'EST UN SOURCE DE BEAUCOUP DE PROBLÈME MAIS COMME JE DÉBUTE EN C++
    LES MÉTHODES QUE VOUS VOYEZ EN CE PROGRAMME C'EST TOUS QUE
    JE SAIS POUR LE MOMENT.
    POUR CE PROBLÈME
    C'est bien pour cela que je te donne une autre solution qui sera bien plus efficace et qui te permettra de travailler de manière plus sécuritaire
    JE CROIS QUE CETTE LIGNE RESOUDRE LE PROBLEME
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    f.m_taille=r.m_taille;
    ET CE LIGNE LA
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    f.m_taille=m_taille;
    Non, et ce serait même pire que tout, car, si f est l'objet à renvoyer, tu va, simplement, mentir sur le nombre d'éléments que peut contenir f, sans pour autant modifier le tableau en lui-même
    ENFIN S.V.P EST QUE VOUS POUVEZ M'INDIQUER COMMENT JE PEUX RÉCUPÉRÉ LE RÉSULTAT DE L'OPÉRATEUR * CORRECTEMENT
    En gardant la solution de l'allocation dynamique, ce pourrait être quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    registre registre::operator*(registre const & r)
    {
        /* sélectionnons la taille la plus grande des deux registres */
        int temptaille=(m_taille>r.m_taille? m_taille:r.m_taille);
        /* et utilisons la pour créer notre objet  renvoyé */
        f(temptaille);
        /* à partir de la, le reste est identique */
        /*...*/
        return f;
    }
    MERCI D'AVANCE POUR VOUS
    De rien...

    Pense cependant que, sur un forum, le fait de tout écrire en majuscules revient à crier...

    Comme j'ai les oreilles sensible, je te remercierais d'éviter de le faire à l'avenir
    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

  5. #5
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 40
    Par défaut
    merci pour vos conseilles, le problème est résolu


    Pense cependant que, sur un forum, le fait de tout écrire en majuscules revient à crier...

    Comme j'ai les oreilles sensible, je te remercierais d'éviter de le faire à l'avenir
    Je m'excuse pour l'écriture en majuscule ( crier) et merci encore pour votre aide.

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

Discussions similaires

  1. surcharge de l'operateur <<
    Par Elay dans le forum C++
    Réponses: 6
    Dernier message: 28/11/2009, 12h13
  2. surcharge de l'operateur >>
    Par hunter99 dans le forum C++
    Réponses: 3
    Dernier message: 02/12/2007, 15h16
  3. Réponses: 3
    Dernier message: 06/04/2007, 20h06
  4. compilation g++ et surcharge de l'operateur =
    Par lionel50 dans le forum Autres éditeurs
    Réponses: 3
    Dernier message: 19/12/2006, 20h48
  5. Réponses: 9
    Dernier message: 25/09/2006, 00h55

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